https://gitlab.synchro.net/main/sbbs/-/commit/c8cf082f019a2f70da40b86b
Added Files:
src/syncterm/ansi_filter.c ansi_filter.h
Modified Files:
src/syncterm/CMakeLists.txt SyncTERM.vcxproj Wren.adoc objects.mk ripper.c src/syncterm/scripts/syncterm.wren src/syncterm/wren_bind.c wren_bind_hook.c wren_bind_hook.h wren_host.c wren_host_internal.h
Log Message:
SyncTERM: shared ANSI filter; Hook.onMatchClean; drop misleading onMatch consume
Lifts ripper.c's `ansi_only` state machine into a reusable pair (`ansi_filter.[ch]`) with two modes — KEEP_ESC (ripper's existing
behavior, drops plain text) and KEEP_TEXT (drops escape sequences,
keeps the text the user actually sees). ripper.c's `ansi_only` is
now a 4-line wrapper, behavior unchanged.
`Hook.onMatchClean(pattern, fn)` is the escape-aware variant of
`onMatch`: inbound bytes are pre-filtered through `ansi_filter` in
KEEP_TEXT mode before reaching the regex VM, so a literal pattern
matches the visible text even when the BBS interleaves colour
codes through it. Per-hook entry tracks its own filter state.
Both `onMatch` and `onMatchClean` are now passthrough-only. The
historical "Bool true to drop the matched bytes" contract on
`onMatch` was misleading — `dispatch_match_drain` only dropped the
single byte that completed the match (every prior byte already
went through cterm), so users never actually got "drop the matched
span." Anyone needing wire-level drop should use Hook.onInput,
which is byte-granular by design. Wren.adoc, the worked-example,
and the hook table all updated.
`check_speedwatch` in term.c was assessed for filter reuse but left
alone — it does sub-byte param validation specific to the speed
response (`ESC [ 0|1 ; digits+ * r`) that the general filter doesn't
help with; wrapping the filter around it requires a CSI-body
buffer plus a post-parser, net code goes up.
Co-Authored-By: Claude Opus 4.7 (1M context) <
noreply@anthropic.com>
---
■ Synchronet ■ Vertrauen ■ Home of Synchronet ■ [vert/cvs/bbs].synchro.net