"""bce.py RAWFILE: report erases/scrolls done while a background colour is set (what a back-colour-erase terminal would paint). Tracks cursor row/col roughly. Claude Opus 5.5, 2026-10-19; written for 2089, https://github.com/nfinit/2089.""" import re, sys data = open(sys.argv[1], 'rb').read().decode('latin-1') row = col = 0; bg = None; out = [] i = 0 seq = re.compile(r'\x1b\[([0-9;?]*)([@-~])|\x1b([()][0-9A-Za-z])|\x1b([0-9A-Za-z=>])') while i < len(data): m = seq.match(data, i) if m: p, f = m.group(1), m.group(2) if f: args = [int(x) if x.isdigit() else 0 for x in (p or '').replace('?', '').split(';')] if p else [] if f == 'm': for a in (args or [0]): if a == 0 or a == 49: bg = None elif 40 <= a <= 47 or 100 <= a <= 107: bg = a elif f == 'H' or f == 'f': row = (args[0] if args and args[0] else 1) - 1 col = (args[1] if len(args) > 1 and args[1] else 1) - 1 elif f == 'A': row -= args[0] if args and args[0] else 1 elif f == 'B': row += args[0] if args and args[0] else 1 elif f == 'C': col += args[0] if args and args[0] else 1 elif f == 'D': col -= args[0] if args and args[0] else 1 elif f in 'KJLMPX@' and bg is not None: out.append('ESC[%s%s at row %d col %d with background %d' % (p, f, row + 1, col + 1, bg)) elif f == 'r': pass elif m.group(4) == 'M': row -= 1 i = m.end(); continue c = data[i] if c == '\n': if row == 23 and bg is not None: out.append('LF scroll at bottom with background %d' % bg) row = min(row + 1, 23) elif c == '\r': col = 0 elif c == '\b': col -= 1 elif c == '\t': col = (col // 8 + 1) * 8 elif c >= ' ': col += 1 i += 1 print('\n'.join(out) if out else 'no erase or scroll while a background colour is set')