forked from Imagelibrary/littlefs
scripts: treemaps: Fixed crashes when there's nothing to show
Crashing on invalid input isn't the _worst_ behavior, but with a few tweaks we can make these scripts more-or-less noop in such cases. This is useful when running with -k/--keep-open since intermediate file states often contain garbage. (Ironically one of the precise problems littlefs is trying to solve.) Also added a special case to treemap.py/codemap.py to not output the canvas if there's nothing to show and height is implicit. Otherwise the history mode with -n/--lines ends up filled with blank lines. Note this makes -H1 subtly different from no -H/--height, with -H1 printing a blank line if there is nothing to show. The -H1 behavior may also be useful in niche cases where you want that part of the screen cleared. --- This was found while trying to run codemap.py -k -n5 during compilation. GCC writes object files incrementally, and this was breaking our script.
This commit is contained in:
@@ -1019,6 +1019,8 @@ def main_(f, paths, *,
|
|||||||
# merge code/stack/ctx results
|
# merge code/stack/ctx results
|
||||||
functions = co.OrderedDict()
|
functions = co.OrderedDict()
|
||||||
for r in results:
|
for r in results:
|
||||||
|
if 'function' not in r:
|
||||||
|
continue
|
||||||
if r['function'] not in functions:
|
if r['function'] not in functions:
|
||||||
functions[r['function']] = {'name': r['function']}
|
functions[r['function']] = {'name': r['function']}
|
||||||
# code things
|
# code things
|
||||||
@@ -1155,6 +1157,10 @@ def main_(f, paths, *,
|
|||||||
|
|
||||||
# assign colors/chars/labels to code tiles
|
# assign colors/chars/labels to code tiles
|
||||||
for i, t in enumerate(code.leaves()):
|
for i, t in enumerate(code.leaves()):
|
||||||
|
# skip the top tile, yes this can happen if we have no code
|
||||||
|
if t.depth == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
t.color = subsystems[t.attrs['subsystem']]['color']
|
t.color = subsystems[t.attrs['subsystem']]['color']
|
||||||
|
|
||||||
if (i, t.attrs['name']) in chars_:
|
if (i, t.attrs['name']) in chars_:
|
||||||
@@ -1218,6 +1224,11 @@ def main_(f, paths, *,
|
|||||||
((total_value * to_scale) / (width_*xscale))
|
((total_value * to_scale) / (width_*xscale))
|
||||||
/ yscale)
|
/ yscale)
|
||||||
|
|
||||||
|
# as a special case, if height is implicit and we have nothing to
|
||||||
|
# show, don't print anything
|
||||||
|
if height is None and nil_code and nil_frames and nil_ctx:
|
||||||
|
height_ = 1 if not no_header else 0
|
||||||
|
|
||||||
# our general purpose partition function
|
# our general purpose partition function
|
||||||
def partition(tile, **args):
|
def partition(tile, **args):
|
||||||
if tile.depth == 0:
|
if tile.depth == 0:
|
||||||
|
|||||||
@@ -750,6 +750,8 @@ def main(paths, output, *,
|
|||||||
# merge code/stack/ctx results
|
# merge code/stack/ctx results
|
||||||
functions = co.OrderedDict()
|
functions = co.OrderedDict()
|
||||||
for r in results:
|
for r in results:
|
||||||
|
if 'function' not in r:
|
||||||
|
continue
|
||||||
if r['function'] not in functions:
|
if r['function'] not in functions:
|
||||||
functions[r['function']] = {'name': r['function']}
|
functions[r['function']] = {'name': r['function']}
|
||||||
# code things
|
# code things
|
||||||
@@ -886,7 +888,12 @@ def main(paths, output, *,
|
|||||||
|
|
||||||
# assign colors/labels to code tiles
|
# assign colors/labels to code tiles
|
||||||
for i, t in enumerate(code.leaves()):
|
for i, t in enumerate(code.leaves()):
|
||||||
|
# skip the top tile, yes this can happen if we have no code
|
||||||
|
if t.depth == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
t.color = subsystems[t.attrs['subsystem']]['color']
|
t.color = subsystems[t.attrs['subsystem']]['color']
|
||||||
|
|
||||||
if (i, t.attrs['name']) in labels_:
|
if (i, t.attrs['name']) in labels_:
|
||||||
label__ = labels_[i, t.attrs['name']]
|
label__ = labels_[i, t.attrs['name']]
|
||||||
# don't punescape unless we have to
|
# don't punescape unless we have to
|
||||||
@@ -1221,6 +1228,9 @@ def main(paths, output, *,
|
|||||||
|
|
||||||
# create code tiles
|
# create code tiles
|
||||||
for i, t in enumerate(code.leaves()):
|
for i, t in enumerate(code.leaves()):
|
||||||
|
# skip the top tile, yes this can happen if we have no code
|
||||||
|
if t.depth == 0:
|
||||||
|
continue
|
||||||
# skip anything with zero weight/height after aligning things
|
# skip anything with zero weight/height after aligning things
|
||||||
if t.width == 0 or t.height == 0:
|
if t.width == 0 or t.height == 0:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -1090,6 +1090,11 @@ def main_(f, csv_paths, *,
|
|||||||
((tile.value * to_scale) / (width_*xscale))
|
((tile.value * to_scale) / (width_*xscale))
|
||||||
/ yscale)
|
/ yscale)
|
||||||
|
|
||||||
|
# as a special case, if height is implicit and we have nothing to
|
||||||
|
# show, don't print anything
|
||||||
|
if height is None and tile.value == 0:
|
||||||
|
height_ = 1 if not no_header else 0
|
||||||
|
|
||||||
# create a canvas
|
# create a canvas
|
||||||
canvas = Canvas(
|
canvas = Canvas(
|
||||||
width_,
|
width_,
|
||||||
|
|||||||
Reference in New Issue
Block a user