https://gitlab.synchro.net/main/sbbs/-/commit/d91e670aaee817fea9820e9e
Modified Files:
docs/v322_new.md src/sbbs3/con_out.cpp str_util.c str_util.h terminal.h Log Message:
bprintf: measure %s field widths in columns rather than bytes
printf counts a field width in bytes, but a terminal renders columns.
For a UTF-8 argument the two differ, so a byte-counted field prints
short and whatever follows it slides left. Every columnar format string
sent to a UTF-8 terminal is affected; message listings are the most
visible case.
Rewrite the numbers instead of the formatting. fmt_col_widths() walks
the conversions in a format string, and for each %s carrying a literal
width or precision re-states them in bytes such that printf's
truncate-then-pad arrives at the requested number of columns: the new
precision is the byte count of the leading N columns, and the new width
is padded by the byte-minus-column difference. vsnprintf still does all
the conversion. Sysop-customized text.dat files therefore keep working untouched, and output to a non-UTF-8 terminal is unchanged, the pre-pass running only for P_UTF8.
A '*' width or precision is left alone: atcode() computes those itself
and has already accounted for the difference, so rewriting them would compensate twice. An unrecognized conversion, a NULL argument, or a
rewrite that would overflow the buffer all return the format string
unmodified.
Widths are measured with Terminal::bstrlen(), which already knows what
occupies a column -- Ctrl-A codes, the PCBoard, Wildcat, Renegade,
Celerity and WWIV sequences, backspace, and UTF-8 code-point widths.
It gains an optional column limit and a byte-count out-parameter, which
is what lets a field be truncated on a column boundary without splitting
a multi-byte sequence.
Issue #1204
Co-Authored-By: Claude Opus 5 (1M context) <
noreply@anthropic.com>
--- SBBSecho 3.37-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)