mdview2: горизонтальный скролл по типу блока + фиксы fence/HR/SDCC

Горизонтальный скролл (Фаза 5, финал):
- Скроллим по ТИПУ, а не по длине: новый флаг IF_HSCROLL ставится только
  на код и таблицы; HR и границы fence (IF_NOWRAP без IF_HSCROLL) не
  двигаются. Блок едет целиком, включая строки короче 80.
- Обход бага кодогенерации SDCC z80: `if (n!=g) g=n;` пишет (n-g) вместо n
  (SUB сравнения затирает A, store переиспользует испорченный A). Лечится
  записью viewport_x ДО сравнения. Минимальный репродьюсер и оба описания
  для трекера — в docs/bugs/sdcc-z80-cmp-store-a/ (воспроизводится на чистом
  sdcc 4.5, в т.ч. с --no-peep → это кодогенератор, не peephole).

Рендеринг:
- Отступленный fence (```c внутри списка) теперь распознаётся: is_fence_raw
  пропускает ведущие пробелы/табы; то же в рендере прячет строку-границу.
- Строки-разделители (HR, ровно 80) больше не участвуют в скролле.

Чистка: удалён мёртвый код (is_fence_delim, get_init_style[_raw], is_cont,
seg_flags). Makefile (mdview/mdview2): iconv UTF-8→CP866 завершается ненулевым
кодом при отбрасывании символов — игнорируем (|| true).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-24 10:11:27 +03:00
parent eab5a2d6ac
commit 138e783e72
11 changed files with 1214 additions and 495 deletions
+25
View File
@@ -0,0 +1,25 @@
/*
* Minimal reproducer — SDCC z80 codegen bug.
*
* "global = local" right after "if (local != global)" stores a WRONG value:
* the SUB used to evaluate the comparison clobbers register A (which still
* holds `n`), and the store reuses that clobbered A.
*
* Build (stock SDCC, no extra flags, no custom toolchain):
* sdcc -mz80 -S repro.c
*
* Tested with: SDCC 4.5.0 #15242 (Mac OS X x86_64), default options.
* Also reproduces with --opt-code-speed and with --no-peep
* (so it is a code-generator bug, not a peephole-optimizer bug).
*
* Expected semantics: after update(n), vx == n whenever n != vx.
* Actual result: vx == (unsigned char)(n - old_vx).
*/
unsigned char vx;
void update(unsigned char n)
{
if (n != vx) {
vx = n;
}
}