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:
@@ -2733,7 +2733,6 @@ class Gstate:
|
||||
locals()[g.__name__.lower()] = ft.cached_property(_parser(g))
|
||||
|
||||
|
||||
# TODO sync
|
||||
# high-level littlefs representation
|
||||
class Lfs:
|
||||
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
|
||||
|
||||
@@ -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: (
|
||||
|
||||
@@ -53,13 +53,6 @@ WEAR_COLORS = ['1;30', '1;30', '1;30', '', '', '', '', '31', '31', '1;31']
|
||||
# erases, so progs are more interesting
|
||||
Z_ORDER = ['prog', 'erase', 'read', 'wear', 'noop']
|
||||
|
||||
# TODO rm
|
||||
#CHARS = 'rpe-'
|
||||
#COLORS = ['32', '35', '34', '90']
|
||||
#
|
||||
#WEAR_CHARS = '-123456789'
|
||||
#WEAR_COLORS = ['90', '', '', '', '', '', '', '35', '35', '1;31']
|
||||
|
||||
CHARS_DOTS = " .':"
|
||||
CHARS_BRAILLE = (
|
||||
'⠀⢀⡀⣀⠠⢠⡠⣠⠄⢄⡄⣄⠤⢤⡤⣤' '⠐⢐⡐⣐⠰⢰⡰⣰⠔⢔⡔⣔⠴⢴⡴⣴'
|
||||
@@ -917,473 +910,6 @@ class TraceBlock:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## space filling Hilbert-curve
|
||||
##
|
||||
## note we memoize the last curve since this is a bit expensive
|
||||
##
|
||||
#@ft.lru_cache(1)
|
||||
#def hilbert_curve(width, height):
|
||||
# # based on generalized Hilbert curves:
|
||||
# # https://github.com/jakubcerveny/gilbert
|
||||
# #
|
||||
# def hilbert_(x, y, a_x, a_y, b_x, b_y):
|
||||
# w = abs(a_x+a_y)
|
||||
# h = abs(b_x+b_y)
|
||||
# a_dx = -1 if a_x < 0 else +1 if a_x > 0 else 0
|
||||
# a_dy = -1 if a_y < 0 else +1 if a_y > 0 else 0
|
||||
# b_dx = -1 if b_x < 0 else +1 if b_x > 0 else 0
|
||||
# b_dy = -1 if b_y < 0 else +1 if b_y > 0 else 0
|
||||
#
|
||||
# # trivial row
|
||||
# if h == 1:
|
||||
# for _ in range(w):
|
||||
# yield (x,y)
|
||||
# x, y = x+a_dx, y+a_dy
|
||||
# return
|
||||
#
|
||||
# # trivial column
|
||||
# if w == 1:
|
||||
# for _ in range(h):
|
||||
# yield (x,y)
|
||||
# x, y = x+b_dx, y+b_dy
|
||||
# return
|
||||
#
|
||||
# a_x_, a_y_ = a_x//2, a_y//2
|
||||
# b_x_, b_y_ = b_x//2, b_y//2
|
||||
# w_ = abs(a_x_+a_y_)
|
||||
# h_ = abs(b_x_+b_y_)
|
||||
#
|
||||
# if 2*w > 3*h:
|
||||
# # prefer even steps
|
||||
# if w_ % 2 != 0 and w > 2:
|
||||
# a_x_, a_y_ = a_x_+a_dx, a_y_+a_dy
|
||||
#
|
||||
# # split in two
|
||||
# yield from hilbert_(x, y, a_x_, a_y_, b_x, b_y)
|
||||
# yield from hilbert_(x+a_x_, y+a_y_, a_x-a_x_, a_y-a_y_, b_x, b_y)
|
||||
# else:
|
||||
# # prefer even steps
|
||||
# if h_ % 2 != 0 and h > 2:
|
||||
# b_x_, b_y_ = b_x_+b_dx, b_y_+b_dy
|
||||
#
|
||||
# # split in three
|
||||
# yield from hilbert_(x, y, b_x_, b_y_, a_x_, a_y_)
|
||||
# yield from hilbert_(x+b_x_, y+b_y_, a_x, a_y, b_x-b_x_, b_y-b_y_)
|
||||
# yield from hilbert_(
|
||||
# x+(a_x-a_dx)+(b_x_-b_dx), y+(a_y-a_dy)+(b_y_-b_dy),
|
||||
# -b_x_, -b_y_, -(a_x-a_x_), -(a_y-a_y_))
|
||||
#
|
||||
# if width >= height:
|
||||
# curve = hilbert_(0, 0, +width, 0, 0, +height)
|
||||
# else:
|
||||
# curve = hilbert_(0, 0, 0, +height, +width, 0)
|
||||
#
|
||||
# return list(curve)
|
||||
#
|
||||
## space filling Z-curve/Lebesgue-curve
|
||||
##
|
||||
## note we memoize the last curve since this is a bit expensive
|
||||
##
|
||||
#@ft.lru_cache(1)
|
||||
#def lebesgue_curve(width, height):
|
||||
# # we create a truncated Z-curve by simply filtering out the points
|
||||
# # that are outside our region
|
||||
# curve = []
|
||||
# for i in range(2**(2*mt.ceil(mt.log2(max(width, height))))):
|
||||
# # we just operate on binary strings here because it's easier
|
||||
# b = '{:0{}b}'.format(i, 2*mt.ceil(mt.log2(i+1)/2))
|
||||
# x = int(b[1::2], 2) if b[1::2] else 0
|
||||
# y = int(b[0::2], 2) if b[0::2] else 0
|
||||
# if x < width and y < height:
|
||||
# curve.append((x, y))
|
||||
#
|
||||
# return curve
|
||||
#
|
||||
#
|
||||
#class Pixel(int):
|
||||
# __slots__ = ()
|
||||
# def __new__(cls, state=0, *,
|
||||
# wear=0,
|
||||
# readed=False,
|
||||
# proged=False,
|
||||
# erased=False):
|
||||
# return super().__new__(cls,
|
||||
# state
|
||||
# | (wear << 3)
|
||||
# | (1 if readed else 0)
|
||||
# | (2 if proged else 0)
|
||||
# | (4 if erased else 0))
|
||||
#
|
||||
# @property
|
||||
# def wear(self):
|
||||
# return self >> 3
|
||||
#
|
||||
# @property
|
||||
# def readed(self):
|
||||
# return (self & 1) != 0
|
||||
#
|
||||
# @property
|
||||
# def proged(self):
|
||||
# return (self & 2) != 0
|
||||
#
|
||||
# @property
|
||||
# def erased(self):
|
||||
# return (self & 4) != 0
|
||||
#
|
||||
# def read(self):
|
||||
# return Pixel(int(self) | 1)
|
||||
#
|
||||
# def prog(self):
|
||||
# return Pixel(int(self) | 2)
|
||||
#
|
||||
# def erase(self):
|
||||
# return Pixel((int(self) | 4) + 8)
|
||||
#
|
||||
# def clear(self):
|
||||
# return Pixel(int(self) & ~7)
|
||||
#
|
||||
# def __or__(self, other):
|
||||
# return Pixel(
|
||||
# (int(self) | int(other)) & 7,
|
||||
# wear=max(self.wear, other.wear))
|
||||
#
|
||||
# def worn(self, max_wear, *,
|
||||
# block_cycles=None,
|
||||
# wear_chars=None,
|
||||
# **_):
|
||||
# if wear_chars is None:
|
||||
# wear_chars = WEAR_CHARS
|
||||
#
|
||||
# if block_cycles:
|
||||
# return self.wear / block_cycles
|
||||
# else:
|
||||
# return self.wear / max(max_wear, len(wear_chars))
|
||||
#
|
||||
# def draw(self, max_wear, char=None, *,
|
||||
# reads=True,
|
||||
# progs=True,
|
||||
# erases=True,
|
||||
# wear=False,
|
||||
# block_cycles=None,
|
||||
# color=True,
|
||||
# dots=False,
|
||||
# braille=False,
|
||||
# chars=None,
|
||||
# wear_chars=None,
|
||||
# colors=None,
|
||||
# wear_colors=None,
|
||||
# **_):
|
||||
# # fallback to default chars/colors
|
||||
# if chars is None:
|
||||
# chars = CHARS
|
||||
# if len(chars) < len(CHARS):
|
||||
# chars = chars + CHARS[len(chars):]
|
||||
#
|
||||
# if colors is None:
|
||||
# colors = COLORS
|
||||
# if len(colors) < len(COLORS):
|
||||
# colors = colors + COLORS[len(colors):]
|
||||
#
|
||||
# if wear_chars is None:
|
||||
# wear_chars = WEAR_CHARS
|
||||
#
|
||||
# if wear_colors is None:
|
||||
# wear_colors = WEAR_COLORS
|
||||
#
|
||||
# # compute char/color
|
||||
# c = chars[3]
|
||||
# f = [colors[3]]
|
||||
#
|
||||
# if wear:
|
||||
# w = min(self.worn(
|
||||
# max_wear,
|
||||
# block_cycles=block_cycles,
|
||||
# wear_chars=wear_chars),
|
||||
# 1)
|
||||
#
|
||||
# c = wear_chars[int(w * (len(wear_chars)-1))]
|
||||
# f.append(wear_colors[int(w * (len(wear_colors)-1))])
|
||||
#
|
||||
# if progs and self.proged:
|
||||
# c = chars[1]
|
||||
# f.append(colors[1])
|
||||
# elif erases and self.erased:
|
||||
# c = chars[2]
|
||||
# f.append(colors[2])
|
||||
# elif reads and self.readed:
|
||||
# c = chars[0]
|
||||
# f.append(colors[0])
|
||||
#
|
||||
# # override char?
|
||||
# if char:
|
||||
# c = char
|
||||
#
|
||||
# # apply colors
|
||||
# if f and color:
|
||||
# c = '%s%s\x1b[m' % (
|
||||
# ''.join('\x1b[%sm' % f_ for f_ in f),
|
||||
# c)
|
||||
#
|
||||
# return c
|
||||
#
|
||||
#
|
||||
#class Bmap:
|
||||
# def __init__(self, *,
|
||||
# block_size=1,
|
||||
# block_count=1,
|
||||
# block_window=None,
|
||||
# off_window=None,
|
||||
# width=1,
|
||||
# height=1,
|
||||
# pixels=None):
|
||||
# # default width to block_window or block_size
|
||||
# if width is None:
|
||||
# if block_window is not None:
|
||||
# width = len(block_window)
|
||||
# else:
|
||||
# width = block_count
|
||||
#
|
||||
# # allocate pixels if not provided
|
||||
# if pixels is None:
|
||||
# pixels = [Pixel() for _ in range(width*height)]
|
||||
#
|
||||
# self.pixels = pixels
|
||||
# self.block_size = block_size
|
||||
# self.block_count = block_count
|
||||
# self.block_window = block_window
|
||||
# self.off_window = off_window
|
||||
# self.width = width
|
||||
# self.height = height
|
||||
#
|
||||
# @property
|
||||
# def _block_window(self):
|
||||
# if self.block_window is None:
|
||||
# return range(0, self.block_count)
|
||||
# else:
|
||||
# return self.block_window
|
||||
#
|
||||
# @property
|
||||
# def _off_window(self):
|
||||
# if self.off_window is None:
|
||||
# return range(0, self.block_size)
|
||||
# else:
|
||||
# return self.off_window
|
||||
#
|
||||
# @property
|
||||
# def _window(self):
|
||||
# return len(self._off_window)*len(self._block_window)
|
||||
#
|
||||
# def _op(self, f, block=None, off=None, size=None):
|
||||
# if block is None:
|
||||
# range_ = range(len(self.pixels))
|
||||
# else:
|
||||
# if off is None:
|
||||
# off, size = 0, self.block_size
|
||||
# elif size is None:
|
||||
# off, size = 0, off
|
||||
#
|
||||
# # map into our window
|
||||
# if block not in self._block_window:
|
||||
# return
|
||||
# block -= self._block_window.start
|
||||
#
|
||||
# size = (max(self._off_window.start,
|
||||
# min(self._off_window.stop, off+size))
|
||||
# - max(self._off_window.start,
|
||||
# min(self._off_window.stop, off)))
|
||||
# off = (max(self._off_window.start,
|
||||
# min(self._off_window.stop, off))
|
||||
# - self._off_window.start)
|
||||
# if size == 0:
|
||||
# return
|
||||
#
|
||||
# # map to our block space
|
||||
# range_ = range(
|
||||
# block*len(self._off_window) + off,
|
||||
# block*len(self._off_window) + off+size)
|
||||
# range_ = range(
|
||||
# (range_.start*len(self.pixels)) // self._window,
|
||||
# (range_.stop*len(self.pixels)) // self._window)
|
||||
# range_ = range(
|
||||
# range_.start,
|
||||
# max(range_.stop, range_.start+1))
|
||||
#
|
||||
# # apply the op
|
||||
# for i in range_:
|
||||
# self.pixels[i] = f(self.pixels[i])
|
||||
#
|
||||
# def read(self, block=None, off=None, size=None):
|
||||
# self._op(Pixel.read, block, off, size)
|
||||
#
|
||||
# def prog(self, block=None, off=None, size=None):
|
||||
# self._op(Pixel.prog, block, off, size)
|
||||
#
|
||||
# def erase(self, block=None, off=None, size=None):
|
||||
# self._op(Pixel.erase, block, off, size)
|
||||
#
|
||||
# def clear(self, block=None, off=None, size=None):
|
||||
# self._op(Pixel.clear, block, off, size)
|
||||
#
|
||||
# def resize(self, *,
|
||||
# block_size=None,
|
||||
# block_count=None,
|
||||
# width=None,
|
||||
# height=None):
|
||||
# block_size = (block_size if block_size is not None
|
||||
# else self.block_size)
|
||||
# block_count = (block_count if block_count is not None
|
||||
# else self.block_count)
|
||||
# width = width if width is not None else self.width
|
||||
# height = height if height is not None else self.height
|
||||
#
|
||||
# if (block_size == self.block_size
|
||||
# and block_count == self.block_count
|
||||
# and width == self.width
|
||||
# and height == self.height):
|
||||
# return
|
||||
#
|
||||
# # transform our pixels
|
||||
# self.block_size = block_size
|
||||
# self.block_count = block_count
|
||||
#
|
||||
# pixels = []
|
||||
# for x in range(width*height):
|
||||
# # map into our old bd space
|
||||
# range_ = range(
|
||||
# (x*self._window) // (width*height),
|
||||
# ((x+1)*self._window) // (width*height))
|
||||
# range_ = range(
|
||||
# range_.start,
|
||||
# max(range_.stop, range_.start+1))
|
||||
#
|
||||
# # aggregate state
|
||||
# pixels.append(ft.reduce(
|
||||
# Pixel.__or__,
|
||||
# self.pixels[range_.start:range_.stop],
|
||||
# Pixel()))
|
||||
#
|
||||
# self.width = width
|
||||
# self.height = height
|
||||
# self.pixels = pixels
|
||||
#
|
||||
# def draw(self, row, *,
|
||||
# reads=False,
|
||||
# progs=False,
|
||||
# erases=False,
|
||||
# wear=False,
|
||||
# hilbert=False,
|
||||
# lebesgue=False,
|
||||
# dots=False,
|
||||
# braille=False,
|
||||
# **args):
|
||||
# # find max wear?
|
||||
# max_wear = None
|
||||
# if wear:
|
||||
# max_wear = max(p.wear for p in self.pixels)
|
||||
#
|
||||
# # fold via a curve?
|
||||
# if hilbert:
|
||||
# grid = [None]*(self.width*self.height)
|
||||
# for (x,y), p in zip(
|
||||
# hilbert_curve(self.width, self.height),
|
||||
# self.pixels):
|
||||
# grid[x + y*self.width] = p
|
||||
# elif lebesgue:
|
||||
# grid = [None]*(self.width*self.height)
|
||||
# for (x,y), p in zip(
|
||||
# lebesgue_curve(self.width, self.height),
|
||||
# self.pixels):
|
||||
# grid[x + y*self.width] = p
|
||||
# else:
|
||||
# grid = self.pixels
|
||||
#
|
||||
# # need to wait for more trace output before rendering
|
||||
# #
|
||||
# # this is sort of a hack that knows the output is going to a terminal
|
||||
# if (braille and self.height < 4) or (dots and self.height < 2):
|
||||
# needed_height = 4 if braille else 2
|
||||
#
|
||||
# self.history = getattr(self, 'history', [])
|
||||
# self.history.append(grid.copy())
|
||||
#
|
||||
# if len(self.history)*self.height < needed_height:
|
||||
# # skip for now
|
||||
# return None
|
||||
#
|
||||
# grid = list(it.chain.from_iterable(
|
||||
# # did we resize?
|
||||
# it.islice(it.chain(h, it.repeat(Pixel())),
|
||||
# self.width*self.height)
|
||||
# for h in self.history))
|
||||
# self.history = []
|
||||
#
|
||||
# line = []
|
||||
# if braille:
|
||||
# # encode into a byte
|
||||
# for x in range(0, self.width, 2):
|
||||
# byte_p = 0
|
||||
# best_p = Pixel()
|
||||
# for i in range(2*4):
|
||||
# p = grid[x+(2-1-(i%2)) + ((row*4)+(4-1-(i//2)))*self.width]
|
||||
# best_p |= p
|
||||
# if ((reads and p.readed)
|
||||
# or (progs and p.proged)
|
||||
# or (erases and p.erased)
|
||||
# or (not reads and not progs and not erases
|
||||
# and wear and p.worn(max_wear, **args) >= 0.7)):
|
||||
# byte_p |= 1 << i
|
||||
#
|
||||
# line.append(best_p.draw(
|
||||
# max_wear,
|
||||
# CHARS_BRAILLE[byte_p],
|
||||
# braille=True,
|
||||
# reads=reads,
|
||||
# progs=progs,
|
||||
# erases=erases,
|
||||
# wear=wear,
|
||||
# **args))
|
||||
# elif dots:
|
||||
# # encode into a byte
|
||||
# for x in range(self.width):
|
||||
# byte_p = 0
|
||||
# best_p = Pixel()
|
||||
# for i in range(2):
|
||||
# p = grid[x + ((row*2)+(2-1-i))*self.width]
|
||||
# best_p |= p
|
||||
# if ((reads and p.readed)
|
||||
# or (progs and p.proged)
|
||||
# or (erases and p.erased)
|
||||
# or (not reads and not progs and not erases
|
||||
# and wear and p.worn(max_wear, **args) >= 0.7)):
|
||||
# byte_p |= 1 << i
|
||||
#
|
||||
# line.append(best_p.draw(
|
||||
# max_wear,
|
||||
# CHARS_DOTS[byte_p],
|
||||
# dots=True,
|
||||
# reads=reads,
|
||||
# progs=progs,
|
||||
# erases=erases,
|
||||
# wear=wear,
|
||||
# **args))
|
||||
# else:
|
||||
# for x in range(self.width):
|
||||
# line.append(grid[x + row*self.width].draw(
|
||||
# max_wear,
|
||||
# reads=reads,
|
||||
# progs=progs,
|
||||
# erases=erases,
|
||||
# wear=wear,
|
||||
# **args))
|
||||
#
|
||||
# return ''.join(line)
|
||||
|
||||
|
||||
|
||||
def main(path='-', *,
|
||||
block_size=None,
|
||||
block_count=None,
|
||||
@@ -1542,36 +1068,6 @@ def main(path='-', *,
|
||||
## trace parser
|
||||
|
||||
# precompute trace regexes
|
||||
|
||||
# TODO rm me
|
||||
# trace_pattern = re.compile(
|
||||
# '^(?P<file>[^:]*):(?P<line>[0-9]+):trace:.*?bd_(?:'
|
||||
# '(?P<create>create\w*)\('
|
||||
# '(?:'
|
||||
# 'block_size=(?P<block_size>\w+)'
|
||||
# '|' 'block_count=(?P<block_count>\w+)'
|
||||
# '|' '.*?' ')*'
|
||||
# '\)'
|
||||
# '|' '(?P<read>read)\('
|
||||
# '\s*(?P<read_ctx>\w+)' '\s*,'
|
||||
# '\s*(?P<read_block>\w+)' '\s*,'
|
||||
# '\s*(?P<read_off>\w+)' '\s*,'
|
||||
# '\s*(?P<read_buffer>\w+)' '\s*,'
|
||||
# '\s*(?P<read_size>\w+)' '\s*\)'
|
||||
# '|' '(?P<prog>prog)\('
|
||||
# '\s*(?P<prog_ctx>\w+)' '\s*,'
|
||||
# '\s*(?P<prog_block>\w+)' '\s*,'
|
||||
# '\s*(?P<prog_off>\w+)' '\s*,'
|
||||
# '\s*(?P<prog_buffer>\w+)' '\s*,'
|
||||
# '\s*(?P<prog_size>\w+)' '\s*\)'
|
||||
# '|' '(?P<erase>erase)\('
|
||||
# '\s*(?P<erase_ctx>\w+)' '\s*,'
|
||||
# '\s*(?P<erase_block>\w+)'
|
||||
# '\s*\(\s*(?P<erase_size>\w+)\s*\)' '\s*\)'
|
||||
# '|' '(?P<sync>sync)\('
|
||||
# '\s*(?P<sync_ctx>\w+)' '\s*\)'
|
||||
# ')\s*$')
|
||||
|
||||
init_pattern = re.compile(
|
||||
'^(?P<file>[^ :]*):(?P<line>[0-9]+):trace:'
|
||||
'.*?bd_createcfg\('
|
||||
@@ -1879,8 +1375,6 @@ def main(path='-', *,
|
||||
b.width = max(b.width, 1)
|
||||
b.height = max(b.height, 1)
|
||||
|
||||
# TODO chars should probably take priority over braille/dots
|
||||
# TODO limit these based on requested ops?
|
||||
# assign chars based on op + block
|
||||
for b in bmap.values():
|
||||
b.chars = {}
|
||||
@@ -1936,8 +1430,6 @@ def main(path='-', *,
|
||||
# render to canvas in a specific z-order that prioritizes
|
||||
# interesting ops
|
||||
for op in reversed(Z_ORDER):
|
||||
# TODO if we're rendering noops as dashes here, should we render
|
||||
# unused as dashes even in usage mode in dbgbmap.py?
|
||||
# don't render noops in braille/dots mode
|
||||
if (braille or dots) and op == 'noop':
|
||||
continue
|
||||
@@ -2047,414 +1539,6 @@ def main(path='-', *,
|
||||
b.clear()
|
||||
|
||||
|
||||
|
||||
# TODO rm me
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# # exclusive wear or reads/progs/erases by default
|
||||
# if not reads and not progs and not erases and not wear:
|
||||
# reads = True
|
||||
# progs = True
|
||||
# erases = True
|
||||
#
|
||||
# # assume a reasonable lines/height if not specified
|
||||
# #
|
||||
# # note that we let height = None if neither hilbert or lebesgue
|
||||
# # are specified, this is a bit special as the default may be less
|
||||
# # than one character in height.
|
||||
# if height is None and (hilbert or lebesgue):
|
||||
# if lines is not None:
|
||||
# height = lines
|
||||
# else:
|
||||
# height = 5
|
||||
#
|
||||
# if lines is None:
|
||||
# if height is not None:
|
||||
# lines = height
|
||||
# else:
|
||||
# lines = 5
|
||||
#
|
||||
# # is bd geometry specified?
|
||||
# if isinstance(block_size, tuple):
|
||||
# block_size, block_count_ = block_size
|
||||
# if block_count is None:
|
||||
# block_count = block_count_
|
||||
#
|
||||
# # try to simplify the block/off/size arguments a bit
|
||||
# if not isinstance(block, dict):
|
||||
# block = {'block': block}
|
||||
# block, off, size = (
|
||||
# block.get('block'),
|
||||
# block.get('off'),
|
||||
# block.get('size'))
|
||||
#
|
||||
# if not isinstance(block, tuple):
|
||||
# block = block,
|
||||
# if isinstance(off, tuple) and len(off) == 1:
|
||||
# off, = off
|
||||
# if isinstance(size, tuple) and len(size) == 1:
|
||||
# if off is None:
|
||||
# off, = size
|
||||
# size = None
|
||||
#
|
||||
# if any(isinstance(b, tuple) and len(b) > 1 for b in block):
|
||||
# print("error: more than one block address?",
|
||||
# file=sys.stderr)
|
||||
# sys.exit(-1)
|
||||
# if isinstance(block[0], tuple):
|
||||
# block = (block[0][0], *block[1:])
|
||||
# if len(block) > 1 and isinstance(block[1], tuple):
|
||||
# block = (block[0], block[1][0])
|
||||
# if isinstance(block[0], tuple):
|
||||
# block, off_ = (block[0][0], *block[1:]), block[0][1]
|
||||
# if off is None:
|
||||
# off = off_
|
||||
# if len(block) > 1 and isinstance(block[1], tuple):
|
||||
# block = (block[0], block[1][0])
|
||||
# if len(block) == 1:
|
||||
# block, = block
|
||||
#
|
||||
# if isinstance(off, tuple):
|
||||
# off, size_ = off[0], off[1] - off[0]
|
||||
# if size is None:
|
||||
# size = size_
|
||||
# if isinstance(size, tuple):
|
||||
# off_, size = off[0], off[1] - off[0]
|
||||
# if off is None:
|
||||
# off = off_
|
||||
#
|
||||
# # is a block window specified?
|
||||
# block_window = None
|
||||
# if block is not None:
|
||||
# if isinstance(block, tuple):
|
||||
# block_window = range(*block)
|
||||
# else:
|
||||
# block_window = range(block, block+1)
|
||||
#
|
||||
# off_window = None
|
||||
# if off is not None or size is not None:
|
||||
# off_ = off if off is not None else 0
|
||||
# size_ = size if size is not None else 1
|
||||
# off_window = range(off_, off_+size_)
|
||||
#
|
||||
# # create our block device representation
|
||||
# bmap = Bmap(
|
||||
# block_size=block_size if block_size is not None else 1,
|
||||
# block_count=block_count if block_count is not None else 1,
|
||||
# block_window=block_window,
|
||||
# off_window=off_window)
|
||||
#
|
||||
# def resize():
|
||||
# nonlocal bmap
|
||||
#
|
||||
# # figure out best width/height
|
||||
# if width is None:
|
||||
# width_ = min(80, shutil.get_terminal_size((80, 5))[0])
|
||||
# elif width:
|
||||
# width_ = width
|
||||
# else:
|
||||
# width_ = shutil.get_terminal_size((80, 5))[0]
|
||||
#
|
||||
# if height is None:
|
||||
# height_ = 0
|
||||
# elif height:
|
||||
# height_ = height
|
||||
# else:
|
||||
# height_ = shutil.get_terminal_size((80, 5))[1]
|
||||
#
|
||||
# # terminal size changed?
|
||||
# if width_ != bmap.width or height_ != bmap.height:
|
||||
# bmap.resize(
|
||||
# # scale if we're printing with dots or braille
|
||||
# width=2*width_ if braille else width_,
|
||||
# height=max(
|
||||
# 1,
|
||||
# 4*height_ if braille
|
||||
# else 2*height_ if dots
|
||||
# else height_))
|
||||
# resize()
|
||||
#
|
||||
# # keep track of some extra info
|
||||
# readed = 0
|
||||
# proged = 0
|
||||
# erased = 0
|
||||
#
|
||||
# # parse a line of trace output
|
||||
# pattern = re.compile(
|
||||
# '^(?P<file>[^:]*):(?P<line>[0-9]+):trace:.*?bd_(?:'
|
||||
# '(?P<create>create\w*)\('
|
||||
# '(?:'
|
||||
# 'block_size=(?P<block_size>\w+)'
|
||||
# '|' 'block_count=(?P<block_count>\w+)'
|
||||
# '|' '.*?' ')*'
|
||||
# '\)'
|
||||
# '|' '(?P<read>read)\('
|
||||
# '\s*(?P<read_ctx>\w+)' '\s*,'
|
||||
# '\s*(?P<read_block>\w+)' '\s*,'
|
||||
# '\s*(?P<read_off>\w+)' '\s*,'
|
||||
# '\s*(?P<read_buffer>\w+)' '\s*,'
|
||||
# '\s*(?P<read_size>\w+)' '\s*\)'
|
||||
# '|' '(?P<prog>prog)\('
|
||||
# '\s*(?P<prog_ctx>\w+)' '\s*,'
|
||||
# '\s*(?P<prog_block>\w+)' '\s*,'
|
||||
# '\s*(?P<prog_off>\w+)' '\s*,'
|
||||
# '\s*(?P<prog_buffer>\w+)' '\s*,'
|
||||
# '\s*(?P<prog_size>\w+)' '\s*\)'
|
||||
# '|' '(?P<erase>erase)\('
|
||||
# '\s*(?P<erase_ctx>\w+)' '\s*,'
|
||||
# '\s*(?P<erase_block>\w+)'
|
||||
# '\s*\(\s*(?P<erase_size>\w+)\s*\)' '\s*\)'
|
||||
# '|' '(?P<sync>sync)\('
|
||||
# '\s*(?P<sync_ctx>\w+)' '\s*\)'
|
||||
# ')\s*$')
|
||||
# def parse(line):
|
||||
# nonlocal bmap
|
||||
# nonlocal readed
|
||||
# nonlocal proged
|
||||
# nonlocal erased
|
||||
#
|
||||
# # string searching is much faster than the regex here, and this
|
||||
# # actually has a big impact given the sheer quantity of how much
|
||||
# # trace output we have to deal with
|
||||
# if 'trace' not in line or 'bd' not in line:
|
||||
# return False
|
||||
# m = pattern.match(line)
|
||||
# if not m:
|
||||
# return False
|
||||
#
|
||||
# if m.group('create'):
|
||||
# # update our block size/count
|
||||
# block_size_ = int(m.group('block_size'), 0)
|
||||
# block_count_ = int(m.group('block_count'), 0)
|
||||
#
|
||||
# if reset:
|
||||
# bmap = Bmap(
|
||||
# block_size=block_size_,
|
||||
# block_count=block_count_,
|
||||
# block_window=bmap.block_window,
|
||||
# off_window=bmap.off_window,
|
||||
# width=bmap.width,
|
||||
# height=bmap.height)
|
||||
# elif ((block_size is None
|
||||
# and block_size_ != bmap.block_size)
|
||||
# or (block_count is None
|
||||
# and block_count_ != bmap.block_count)):
|
||||
# bmap.resize(
|
||||
# block_size=block_size if block_size is not None
|
||||
# else block_size_,
|
||||
# block_count=block_count if block_count is not None
|
||||
# else block_count_)
|
||||
# return True
|
||||
#
|
||||
# elif m.group('read') and reads:
|
||||
# block = int(m.group('read_block'), 0)
|
||||
# off = int(m.group('read_off'), 0)
|
||||
# size = int(m.group('read_size'), 0)
|
||||
#
|
||||
# if ((block_size is None and off+size > bmap.block_size)
|
||||
# or (block_count is None and block >= bmap.block_count)):
|
||||
# bmap.resize(
|
||||
# block_size=block_size if block_size is not None
|
||||
# else max(off+size, bmap.block_size),
|
||||
# block_count=block_count if block_count is not None
|
||||
# else max(block+1, bmap.block_count))
|
||||
#
|
||||
# bmap.read(block, off, size)
|
||||
# readed += size
|
||||
# return True
|
||||
#
|
||||
# elif m.group('prog') and progs:
|
||||
# block = int(m.group('prog_block'), 0)
|
||||
# off = int(m.group('prog_off'), 0)
|
||||
# size = int(m.group('prog_size'), 0)
|
||||
#
|
||||
# if ((block_size is None and off+size > bmap.block_size)
|
||||
# or (block_count is None and block >= bmap.block_count)):
|
||||
# bmap.resize(
|
||||
# block_size=block_size if block_size is not None
|
||||
# else max(off+size, bmap.block_size),
|
||||
# block_count=block_count if block_count is not None
|
||||
# else max(block+1, bmap.block_count))
|
||||
#
|
||||
# bmap.prog(block, off, size)
|
||||
# proged += size
|
||||
# return True
|
||||
#
|
||||
# elif m.group('erase') and (erases or wear):
|
||||
# block = int(m.group('erase_block'), 0)
|
||||
# size = int(m.group('erase_size'), 0)
|
||||
#
|
||||
# if ((block_size is None and size > bmap.block_size)
|
||||
# or (block_count is None and block >= bmap.block_count)):
|
||||
# bmap.resize(
|
||||
# block_size=block_size if block_size is not None
|
||||
# else max(size, bmap.block_size),
|
||||
# block_count=block_count if block_count is not None
|
||||
# else max(block+1, bmap.block_count))
|
||||
#
|
||||
# bmap.erase(block, size)
|
||||
# erased += size
|
||||
# return True
|
||||
#
|
||||
# else:
|
||||
# return False
|
||||
#
|
||||
# # print trace output
|
||||
# def draw(f):
|
||||
# nonlocal readed
|
||||
# nonlocal proged
|
||||
# nonlocal erased
|
||||
#
|
||||
# def writeln(s=''):
|
||||
# f.write(s)
|
||||
# f.write('\n')
|
||||
# f.writeln = writeln
|
||||
#
|
||||
# # don't forget we've scaled this for braille/dots!
|
||||
# for row in range(
|
||||
# mt.ceil(bmap.height/4) if braille
|
||||
# else mt.ceil(bmap.height/2) if dots
|
||||
# else bmap.height):
|
||||
# line = bmap.draw(row,
|
||||
# reads=reads,
|
||||
# progs=progs,
|
||||
# erases=erases,
|
||||
# wear=wear,
|
||||
# block_cycles=block_cycles,
|
||||
# color=color,
|
||||
# dots=dots,
|
||||
# braille=braille,
|
||||
# hilbert=hilbert,
|
||||
# lebesgue=lebesgue,
|
||||
# **args)
|
||||
# if line:
|
||||
# f.writeln(line)
|
||||
#
|
||||
# # print some information about reads/progs/erases
|
||||
# #
|
||||
# # cat implies no-header, because a header wouldn't really make sense
|
||||
# if not no_header and not cat:
|
||||
# # compute total ops
|
||||
# total = readed+proged+erased
|
||||
#
|
||||
# # compute stddev of wear using our bmap, this is a bit different
|
||||
# # from reads/progs/erases which ignores any bmap window, but it's
|
||||
# # what we have
|
||||
# if wear:
|
||||
# mean = (sum(p.wear for p in bmap.pixels)
|
||||
# / max(len(bmap.pixels), 1))
|
||||
# stddev = mt.sqrt(sum((p.wear - mean)**2 for p in bmap.pixels)
|
||||
# / max(len(bmap.pixels), 1))
|
||||
# worst = max((p.wear for p in bmap.pixels), default=0)
|
||||
#
|
||||
# # a bit of a hack here, but this forces our header to always be
|
||||
# # at row zero
|
||||
# if len(f.lines) == 0:
|
||||
# f.lines.append('')
|
||||
# f.lines[0] = 'bd %dx%d%s%s%s%s' % (
|
||||
# bmap.block_size, bmap.block_count,
|
||||
# ', %6s read' % ('%.1f%%' % (100*readed / max(total, 1)))
|
||||
# if reads else '',
|
||||
# ', %6s prog' % ('%.1f%%' % (100*proged / max(total, 1)))
|
||||
# if progs else '',
|
||||
# ', %6s erase' % ('%.1f%%' % (100*erased / max(total, 1)))
|
||||
# if erases else '',
|
||||
# ', %13s wear' % ('%.1fσ (%.1f%%)' % (
|
||||
# worst / max(stddev, 1),
|
||||
# 100*stddev / max(worst, 1)))
|
||||
# if wear else '')
|
||||
#
|
||||
# bmap.clear()
|
||||
# readed = 0
|
||||
# proged = 0
|
||||
# erased = 0
|
||||
# resize()
|
||||
#
|
||||
#
|
||||
# # read/parse/coalesce operations
|
||||
# if cat:
|
||||
# ring = sys.stdout
|
||||
# else:
|
||||
# ring = RingIO(lines + (1 if not no_header else 0), head)
|
||||
#
|
||||
# # if sleep print in background thread to avoid getting stuck in a read call
|
||||
# event = th.Event()
|
||||
# lock = th.Lock()
|
||||
# if sleep:
|
||||
# done = False
|
||||
# def background():
|
||||
# while not done:
|
||||
# event.wait()
|
||||
# event.clear()
|
||||
# with lock:
|
||||
# draw(ring)
|
||||
# if not cat:
|
||||
# ring.draw()
|
||||
# # sleep a minimum amount of time to avoid flickering
|
||||
# time.sleep(sleep or 0.01)
|
||||
# th.Thread(target=background, daemon=True).start()
|
||||
#
|
||||
# try:
|
||||
# while True:
|
||||
# with openio(path) as f:
|
||||
# changed = 0
|
||||
# for line in f:
|
||||
# with lock:
|
||||
# changed += parse(line)
|
||||
#
|
||||
# # need to redraw?
|
||||
# if changed and (not coalesce or changed >= coalesce):
|
||||
# if sleep:
|
||||
# event.set()
|
||||
# else:
|
||||
# draw(ring)
|
||||
# if not cat:
|
||||
# ring.draw()
|
||||
# changed = 0
|
||||
#
|
||||
# if not keep_open:
|
||||
# break
|
||||
# # don't just flood open calls
|
||||
# time.sleep(sleep or 2)
|
||||
# except FileNotFoundError as e:
|
||||
# print("error: file not found %r" % path,
|
||||
# file=sys.stderr)
|
||||
# sys.exit(-1)
|
||||
# except KeyboardInterrupt:
|
||||
# pass
|
||||
#
|
||||
# if sleep:
|
||||
# done = True
|
||||
# lock.acquire() # avoids https://bugs.python.org/issue42717
|
||||
# if not cat:
|
||||
# sys.stdout.write('\n')
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# def trace_(line):
|
||||
# # TODO
|
||||
#
|
||||
# # TODO adopt f -> ring name in all scripts?
|
||||
# def draw_(ring, *,
|
||||
# width=None,
|
||||
# height=None):
|
||||
# # TODO
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## main loop
|
||||
lock = th.Lock()
|
||||
event = th.Event()
|
||||
@@ -2489,15 +1573,12 @@ def main(path='-', *,
|
||||
# keep track of history if lines specified
|
||||
if lines is not None:
|
||||
ring = RingIO(lines+1
|
||||
# TODO expose no_header in other scripts for consistency
|
||||
if not no_header and lines > 0
|
||||
else lines)
|
||||
def draw_():
|
||||
# cat? write directly to stdout
|
||||
if cat:
|
||||
draw__(sys.stdout,
|
||||
# TODO copy this pattern (width+height) for
|
||||
# other scripts?
|
||||
width=width,
|
||||
# make space for shell prompt
|
||||
height=-1 if height is ... else height)
|
||||
@@ -2545,25 +1626,6 @@ def main(path='-', *,
|
||||
sys.stdout.write('\n')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# # TODO WIP
|
||||
#
|
||||
# # cat? let main_ write directly to stdout
|
||||
# else:
|
||||
# main_(sys.stdout)
|
||||
#
|
||||
# # not cat? write to a bounded ring
|
||||
# if not cat:
|
||||
# ring = RingIO(lines, head=head)
|
||||
# main_(ring)
|
||||
# sys.stdout.write('\n')
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
import argparse
|
||||
@@ -2759,7 +1821,6 @@ if __name__ == "__main__":
|
||||
'--padding',
|
||||
type=float,
|
||||
help="Padding to add to each block. Defaults to 0.")
|
||||
# TODO lines in dbgbmap.py?
|
||||
parser.add_argument(
|
||||
'-n', '--lines',
|
||||
nargs='?',
|
||||
|
||||
Reference in New Issue
Block a user