mdview2: лимит файла 256 КБ, обрыв с сообщением вместо потери строк
- MAX_PAGES 8->16 (256 КБ), MAX_INDEX_PAGES/MAX_CACHE_DIR_PAGES 8->9 (18432 строк), кап контент-кэша 64->40 стр./набор (80 на оба). Бюджет worst-case (UTF-8 Latin+BOM): ~150 из 215 EMM-страниц. - При исчерпании контент-кэша (cache_reserve==0) или лимита строк индексация обрывается и последняя строка заменяется предупреждением (IF_TRUNC_MSG, рисуется вживую с ATTR_WARN — жёлтый по красному), без хвоста пустых строк. Раньше переполнение молча давало len=0 (пустые строки) без какого-либо индикатора. - help: лимиты обновлены (256 КБ / 18432 строк). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -241,6 +241,12 @@ uint8_t g_ncells = 0; /* ячеек в текущем сег
|
||||
static uint8_t g_ncells_at_space = 0; /* снимок g_ncells на последнем пробеле (для усечения при переносе) */
|
||||
static uint8_t g_skip_flush = 0; /* следующий emit_seg пропустит lag-флаш (pending уже зафлашен вручную, напр. перед таблицей) */
|
||||
|
||||
/* Обрыв индексации: причина (0 / TRUNC_CONTENT / TRUNC_LINES) и строка, на
|
||||
* которой упёрлись. Выставляются ОДИН раз (первая причина побеждает); по ним
|
||||
* index_lines() в конце пишет строку-сообщение (IF_TRUNC_MSG, рисуется вживую). */
|
||||
static uint8_t g_trunc_cause = 0;
|
||||
static uint16_t g_trunc_line = 0;
|
||||
|
||||
/* Пишет одну (char,attr)-ячейку в g_cells, молча игнорируя переполнение
|
||||
* MAX_CACHE_LINE_LEN. Оставлена ФУНКЦИЕЙ намеренно: инлайн в сильно
|
||||
* регистро-нагруженный скан-цикл на Z80/SDCC увеличивает спиллы и замедляет
|
||||
@@ -274,6 +280,9 @@ static void seg_commit_cells(uint16_t line_idx)
|
||||
if (cache_reserve((uint16_t)(g_ncells * 2u), &out_rec.page, &out_rec.off)) {
|
||||
cache_commit(out_rec.page, out_rec.off, g_cells, (uint16_t)(g_ncells * 2u));
|
||||
} else {
|
||||
/* Контент-кэш исчерпан: фиксируем причину и строку обрыва (один раз).
|
||||
* index_lines() оборвёт цикл и перезапишет эту строку сообщением. */
|
||||
if (!g_trunc_cause) { g_trunc_cause = TRUNC_CONTENT; g_trunc_line = line_idx; }
|
||||
out_rec.page = 0; out_rec.off = 0; out_rec.len = 0;
|
||||
}
|
||||
cache_dir_put(line_idx, &out_rec);
|
||||
@@ -283,7 +292,11 @@ static void seg_commit_cells(uint16_t line_idx)
|
||||
static void emit_seg(uint32_t off, uint8_t style, uint8_t ckind, uint8_t cont)
|
||||
{
|
||||
(void)ckind; /* тип сегмента восстанавливается флагами idx-записи */
|
||||
if (n_lines >= max_lines) { index_truncated = 1; return; }
|
||||
if (n_lines >= max_lines) {
|
||||
index_truncated = 1;
|
||||
if (!g_trunc_cause) { g_trunc_cause = TRUNC_LINES; g_trunc_line = (uint16_t)(max_lines - 1); }
|
||||
return;
|
||||
}
|
||||
cur_rec.off = off;
|
||||
cur_rec.flags = (uint8_t)(cont ? IF_CONT : 0);
|
||||
cur_rec.style = (uint8_t)(style & 7u);
|
||||
@@ -687,11 +700,13 @@ void index_lines(void)
|
||||
uint8_t in_block = 0;
|
||||
n_lines = 0;
|
||||
index_truncated = 0;
|
||||
g_trunc_cause = 0;
|
||||
g_trunc_line = 0;
|
||||
cur_seg_off = 0xFFFFFFFFu; /* пока не эмитили ни одного сегмента */
|
||||
if (file_size == 0) return;
|
||||
|
||||
uint32_t p = 0;
|
||||
while (p < file_size && n_lines < max_lines && !g_abort) {
|
||||
while (p < file_size && n_lines < max_lines && !g_abort && !g_trunc_cause) {
|
||||
|
||||
/* UTF-8: держим конвертацию впереди позиции чтения (включая look-ahead
|
||||
* склейки/классификации ~ один абзац). file_size при этом = доступная
|
||||
@@ -957,6 +972,19 @@ void index_lines(void)
|
||||
* комментарий) — последняя эмитированная строка файла так и остаётся
|
||||
* незафлашенной, её ячейки ещё в g_cells; коммитим здесь. */
|
||||
if (n_lines > 0) seg_commit_cells((uint16_t)(n_lines - 1));
|
||||
|
||||
/* Обрыв по контенту/лимиту строк (не путать с пользовательским g_abort):
|
||||
* документ заканчиваем строкой-сообщением на g_trunc_line. Сообщение
|
||||
* рисуется вживую (IF_TRUNC_MSG) — место в контент-кэше ему не нужно, что
|
||||
* и снимает тупик «кэш полон, а сообщение тоже надо закэшировать». */
|
||||
if (g_trunc_cause && !g_abort) {
|
||||
cache_rec_t r;
|
||||
r.page = 0; r.off = 0; r.len = 0;
|
||||
r.flags = IF_TRUNC_MSG; r.reserved = g_trunc_cause;
|
||||
r.pad[0] = 0; r.pad[1] = 0;
|
||||
cache_dir_put(g_trunc_line, &r);
|
||||
n_lines = (uint16_t)(g_trunc_line + 1); /* документ кончается на строке-обрыве */
|
||||
}
|
||||
}
|
||||
#define EM_NONE 0
|
||||
#define EM_BOLD 1
|
||||
|
||||
Reference in New Issue
Block a user