scripts: Consistent table renderer, cycle detection optional

The fact that our scripts' table renderer was slightly different for
recursive scripts (stack.py, perf.py) and non-recursive scripts
(code.py, structs.py) was a ticking time bomb, one innocent edit away
from breaking half the scripts.

The makes the table renderer consistent across all scripts, allowing for
easy copy-pasting when editing at the cost of some unused code in
scripts.

One hiccup with this though is the difference in cycle detection
behavior between scripts:

- stack.py:

    lfsr_bd_sync
    '-> lfsr_bd_prog
        '-> lfsr_bd_sync  <-- cycle!

- structs.py:

    lfsr_bshrub_t
    '-> u
        '-> bsprout
            '-> u  <-- not a cycle!

To solve this the table renderer now accepts a simple detect_cycles
flag, which can be set per-script.
This commit is contained in:
Christopher Haster
2024-11-27 01:25:55 -06:00
parent 7c8afd26cf
commit e00db216c1
8 changed files with 421 additions and 42 deletions

View File

@@ -696,8 +696,9 @@ def table(Result, results, diff_results=None, *,
all=False,
compare=None,
summary=False,
depth=None,
depth=1,
hot=None,
detect_cycles=True,
**_):
all_, all = all, __builtins__.all
@@ -731,7 +732,8 @@ def table(Result, results, diff_results=None, *,
for k in it.chain(hot, [None])))
# found a cycle?
if tuple(getattr(r, k) for k in Result._by) in seen:
if (detect_cycles
and tuple(getattr(r, k) for k in Result._by) in seen):
return []
return [r._replace(children=[])] + rec_hot(
@@ -753,9 +755,9 @@ def table(Result, results, diff_results=None, *,
or all_
or any(
types[k].ratio(
getattr(table.get(name), k, None),
getattr(diff_table.get(name), k, None))
for k in fields)]
getattr(table.get(name), k, None),
getattr(diff_table.get(name), k, None))
for k in fields)]
# find compare entry if there is one
if compare:
@@ -881,7 +883,7 @@ def table(Result, results, diff_results=None, *,
getattr(diff_r, k, None)))))
return entry
# recursive entry helper
# recursive entry helper, only used by some scripts
def recurse(results_, depth_, seen=set(),
prefixes=('', '', '', '')):
# build the children table at each layer
@@ -916,12 +918,12 @@ def table(Result, results, diff_results=None, *,
# add prefixes
line[0] = (prefixes[0+is_last] + line[0][0], line[0][1])
# add cycle detection
if name in seen:
if detect_cycles and name in seen:
line[-1] = (line[-1][0], line[-1][1] + ['cycle detected'])
lines.append(line)
# found a cycle?
if name in seen:
if detect_cycles and name in seen:
continue
# recurse?