From e3342b63f33f859b93239fc66145948bb24e7e3b Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Tue, 30 Jun 2026 22:13:29 +0300 Subject: [PATCH] =?UTF-8?q?mdview2:=20=D1=87=D0=B8=D0=BD=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20=D0=B4=D0=B5=D1=82=D0=B5=D0=BA=D1=82=20=D0=BB=D0=B8=D0=BC?= =?UTF-8?q?=D0=B8=D1=82=D0=B0=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=20+=20?= =?UTF-8?q?=D0=BA=D0=BB=D0=B0=D0=BC=D0=BF=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2=20>256=20=D0=9A=D0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Лимит строк не показывал предупреждение: g_trunc_cause=TRUNC_LINES ставился в emit_seg, но главный цикл выходит по n_lines256 КБ больше не отвергаем экраном ошибки, а КЛАМПим: читаем первые 256 КБ, индексатор дописывает строку TRUNC_FILE (File too large - truncated at 256 KB). Приоритет ниже content/lines. Текст ошибки -2 поправлен (был 'size > 128K'). Co-Authored-By: Claude Opus 4.8 --- examples/mdview2/mdview2.c | 12 ++++++++++-- examples/mdview2/mdview2.h | 2 ++ examples/mdview2/mdview2_index.c | 19 +++++++++++++++++++ examples/mdview2/mdview2_md.c | 12 +++++++----- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/examples/mdview2/mdview2.c b/examples/mdview2/mdview2.c index 168b303..49c1621 100644 --- a/examples/mdview2/mdview2.c +++ b/examples/mdview2/mdview2.c @@ -186,6 +186,7 @@ uint8_t index_blk = 0; /* extern: дескриптор uint8_t index_pages = 0; /* */ uint8_t index_phys[MAX_INDEX_PAGES] = {0}; /* extern: физ. страницы индекса */ uint8_t index_truncated = 0; /* выставляется при исчерпании ёмкости индекса */ +uint8_t g_file_clamped = 0; /* extern: файл >256 КБ обрезан до MAX_FILE при загрузке */ /* cur_seg_off/cur_rec (near-состояние индексатора) — в mdview2_index.c. */ uint8_t cur_page = 0xFF; /* extern: 0xFF = в W3 ещё не показана ни одна страница (extern: кодек инвалидирует) */ @@ -444,10 +445,17 @@ static int load_file(const char *path) return -1; long sz = lseek(fd, 0, SEEK_END); - if (sz < 0 || (uint32_t)sz > MAX_FILE) { + if (sz < 0) { close(fd); return -2; } + /* Файл больше MAX_FILE (256 КБ) не отвергаем, а КЛАМПим: читаем первые + * 256 КБ, индексатор допишет строку-предупреждение (TRUNC_FILE). */ + g_file_clamped = 0; + if ((uint32_t)sz > MAX_FILE) { + sz = (long)MAX_FILE; + g_file_clamped = 1; + } file_size = (uint32_t)sz; lseek(fd, 0, SEEK_SET); @@ -911,7 +919,7 @@ int main(int argc, char **argv) cputs("'\n\rError: "); switch (rc) { case -1: cputs("open failed"); break; - case -2: cputs("size > 128K or seek failed"); break; + case -2: cputs("seek failed"); break; case -3: cputs("mem_alloc_pages failed"); break; case -4: cputs("short read"); break; case -5: cputs("index alloc failed"); break; diff --git a/examples/mdview2/mdview2.h b/examples/mdview2/mdview2.h index ac335a5..de3d1ad 100644 --- a/examples/mdview2/mdview2.h +++ b/examples/mdview2/mdview2.h @@ -94,6 +94,7 @@ /* ---- Причина обрыва индексации (cache_rec.reserved при IF_TRUNC_MSG) ---- */ #define TRUNC_CONTENT 1 /* исчерпан контент-кэш (MAX_CACHE_CONTENT_PAGES) */ #define TRUNC_LINES 2 /* исчерпана ёмкость индекса (max_lines) */ +#define TRUNC_FILE 3 /* файл больше MAX_FILE — прочитаны первые 256 КБ */ /* ---- Словарь сегментов/стилей (общий для индексатора и таблиц) ---- */ /* Тип сегмента-продолжения, передаваемый в emit_seg()/inline_scan(). */ @@ -221,6 +222,7 @@ extern uint8_t index_blk, index_pages; /* дескриптор EMM-блока extern uint8_t index_phys[]; /* физ. страницы индекса */ extern uint8_t index_truncated; /* индекс упёрся в ёмкость */ extern uint8_t g_abort; /* F10/Esc во время загрузки → прервать индексацию */ +extern uint8_t g_file_clamped; /* файл был обрезан до MAX_FILE при загрузке (>256 КБ) */ uint8_t cache_reserve(uint16_t nbytes, uint8_t *out_page, uint16_t *out_off); void cache_commit(uint8_t page, uint16_t off, const void *buf, uint16_t len); diff --git a/examples/mdview2/mdview2_index.c b/examples/mdview2/mdview2_index.c index cc551a0..bad17ad 100644 --- a/examples/mdview2/mdview2_index.c +++ b/examples/mdview2/mdview2_index.c @@ -973,6 +973,25 @@ void index_lines(void) * незафлашенной, её ячейки ещё в g_cells; коммитим здесь. */ if (n_lines > 0) seg_commit_cells((uint16_t)(n_lines - 1)); + /* Лимит строк ловим ЗДЕСЬ, а не в emit_seg: главный цикл выходит по + * `n_lines < max_lines` ДО того, как emit_seg будет вызван в переполненном + * состоянии (для code-block — один emit_seg на строку, эта ветка не + * достигается). Признак — остановились, а файл не кончился; g_abort и + * исчерпание контента (TRUNC_CONTENT) уже обработаны/исключены. */ + if (!g_trunc_cause && !g_abort && p < file_size) { + g_trunc_cause = TRUNC_LINES; + g_trunc_line = (uint16_t)(max_lines - 1); + } + + /* Файл был обрезан до 256 КБ при загрузке, а индексация дошла до конца + * клампнутых данных без исчерпания контента/строк → ДОПИСЫВАЕМ строку + * (место есть: n_lines < max_lines). Приоритет ниже content/lines — + * те означают, что обрезали ещё раньше, их сообщение точнее. */ + if (!g_trunc_cause && !g_abort && g_file_clamped) { + g_trunc_cause = TRUNC_FILE; + g_trunc_line = n_lines; + } + /* Обрыв по контенту/лимиту строк (не путать с пользовательским g_abort): * документ заканчиваем строкой-сообщением на g_trunc_line. Сообщение * рисуется вживую (IF_TRUNC_MSG) — место в контент-кэше ему не нужно, что diff --git a/examples/mdview2/mdview2_md.c b/examples/mdview2/mdview2_md.c index 697da83..a14c952 100644 --- a/examples/mdview2/mdview2_md.c +++ b/examples/mdview2/mdview2_md.c @@ -31,13 +31,15 @@ static void draw_line_from_cache(uint16_t line_idx, uint8_t row) /* Строка-обрыв (исчерпан контент-кэш / лимит строк): фикс. текст вживую, * без обращения к контент-кэшу (см. index_lines финализацию). */ if (rec.flags & IF_TRUNC_MSG) { + const char *msg; + switch (rec.reserved) { + case TRUNC_LINES: msg = "*** Line limit reached - document truncated ***"; break; + case TRUNC_FILE: msg = "*** File too large - truncated at 256 KB ***"; break; + default: msg = "*** Content cache exhausted - document truncated ***"; break; + } bios_set_place(row, 0); bios_fillcharattr(' ', ATTR_WARN, SCREEN_W); - put_str_attr(2, row, - (rec.reserved == TRUNC_LINES) - ? "*** Line limit reached - document truncated ***" - : "*** Content cache exhausted - document truncated ***", - ATTR_WARN); + put_str_attr(2, row, msg, ATTR_WARN); return; }