mdview2: чинить детект лимита строк + кламп файлов >256 КБ
1. Лимит строк не показывал предупреждение: g_trunc_cause=TRUNC_LINES ставился в emit_seg, но главный цикл выходит по n_lines<max_lines ДО вызова emit_seg в переполненном состоянии (для code-block — один emit_seg на строку). Теперь ловим после цикла по признаку p<file_size (остановились, файл не кончился). 2. Файл >256 КБ больше не отвергаем экраном ошибки, а КЛАМПим: читаем первые 256 КБ, индексатор дописывает строку TRUNC_FILE (File too large - truncated at 256 KB). Приоритет ниже content/lines. Текст ошибки -2 поправлен (был 'size > 128K'). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -186,6 +186,7 @@ uint8_t index_blk = 0; /* extern: дескриптор
|
|||||||
uint8_t index_pages = 0; /* */
|
uint8_t index_pages = 0; /* */
|
||||||
uint8_t index_phys[MAX_INDEX_PAGES] = {0}; /* extern: физ. страницы индекса */
|
uint8_t index_phys[MAX_INDEX_PAGES] = {0}; /* extern: физ. страницы индекса */
|
||||||
uint8_t index_truncated = 0; /* выставляется при исчерпании ёмкости индекса */
|
uint8_t index_truncated = 0; /* выставляется при исчерпании ёмкости индекса */
|
||||||
|
uint8_t g_file_clamped = 0; /* extern: файл >256 КБ обрезан до MAX_FILE при загрузке */
|
||||||
|
|
||||||
/* cur_seg_off/cur_rec (near-состояние индексатора) — в mdview2_index.c. */
|
/* cur_seg_off/cur_rec (near-состояние индексатора) — в mdview2_index.c. */
|
||||||
uint8_t cur_page = 0xFF; /* extern: 0xFF = в W3 ещё не показана ни одна страница (extern: кодек инвалидирует) */
|
uint8_t cur_page = 0xFF; /* extern: 0xFF = в W3 ещё не показана ни одна страница (extern: кодек инвалидирует) */
|
||||||
@@ -444,10 +445,17 @@ static int load_file(const char *path)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
long sz = lseek(fd, 0, SEEK_END);
|
long sz = lseek(fd, 0, SEEK_END);
|
||||||
if (sz < 0 || (uint32_t)sz > MAX_FILE) {
|
if (sz < 0) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return -2;
|
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;
|
file_size = (uint32_t)sz;
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
@@ -911,7 +919,7 @@ int main(int argc, char **argv)
|
|||||||
cputs("'\n\rError: ");
|
cputs("'\n\rError: ");
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
case -1: cputs("open failed"); break;
|
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 -3: cputs("mem_alloc_pages failed"); break;
|
||||||
case -4: cputs("short read"); break;
|
case -4: cputs("short read"); break;
|
||||||
case -5: cputs("index alloc failed"); break;
|
case -5: cputs("index alloc failed"); break;
|
||||||
|
|||||||
@@ -94,6 +94,7 @@
|
|||||||
/* ---- Причина обрыва индексации (cache_rec.reserved при IF_TRUNC_MSG) ---- */
|
/* ---- Причина обрыва индексации (cache_rec.reserved при IF_TRUNC_MSG) ---- */
|
||||||
#define TRUNC_CONTENT 1 /* исчерпан контент-кэш (MAX_CACHE_CONTENT_PAGES) */
|
#define TRUNC_CONTENT 1 /* исчерпан контент-кэш (MAX_CACHE_CONTENT_PAGES) */
|
||||||
#define TRUNC_LINES 2 /* исчерпана ёмкость индекса (max_lines) */
|
#define TRUNC_LINES 2 /* исчерпана ёмкость индекса (max_lines) */
|
||||||
|
#define TRUNC_FILE 3 /* файл больше MAX_FILE — прочитаны первые 256 КБ */
|
||||||
|
|
||||||
/* ---- Словарь сегментов/стилей (общий для индексатора и таблиц) ---- */
|
/* ---- Словарь сегментов/стилей (общий для индексатора и таблиц) ---- */
|
||||||
/* Тип сегмента-продолжения, передаваемый в emit_seg()/inline_scan(). */
|
/* Тип сегмента-продолжения, передаваемый в 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_phys[]; /* физ. страницы индекса */
|
||||||
extern uint8_t index_truncated; /* индекс упёрся в ёмкость */
|
extern uint8_t index_truncated; /* индекс упёрся в ёмкость */
|
||||||
extern uint8_t g_abort; /* F10/Esc во время загрузки → прервать индексацию */
|
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);
|
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);
|
void cache_commit(uint8_t page, uint16_t off, const void *buf, uint16_t len);
|
||||||
|
|||||||
@@ -973,6 +973,25 @@ void index_lines(void)
|
|||||||
* незафлашенной, её ячейки ещё в g_cells; коммитим здесь. */
|
* незафлашенной, её ячейки ещё в g_cells; коммитим здесь. */
|
||||||
if (n_lines > 0) seg_commit_cells((uint16_t)(n_lines - 1));
|
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_abort):
|
||||||
* документ заканчиваем строкой-сообщением на g_trunc_line. Сообщение
|
* документ заканчиваем строкой-сообщением на g_trunc_line. Сообщение
|
||||||
* рисуется вживую (IF_TRUNC_MSG) — место в контент-кэше ему не нужно, что
|
* рисуется вживую (IF_TRUNC_MSG) — место в контент-кэше ему не нужно, что
|
||||||
|
|||||||
@@ -31,13 +31,15 @@ static void draw_line_from_cache(uint16_t line_idx, uint8_t row)
|
|||||||
/* Строка-обрыв (исчерпан контент-кэш / лимит строк): фикс. текст вживую,
|
/* Строка-обрыв (исчерпан контент-кэш / лимит строк): фикс. текст вживую,
|
||||||
* без обращения к контент-кэшу (см. index_lines финализацию). */
|
* без обращения к контент-кэшу (см. index_lines финализацию). */
|
||||||
if (rec.flags & IF_TRUNC_MSG) {
|
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_set_place(row, 0);
|
||||||
bios_fillcharattr(' ', ATTR_WARN, SCREEN_W);
|
bios_fillcharattr(' ', ATTR_WARN, SCREEN_W);
|
||||||
put_str_attr(2, row,
|
put_str_attr(2, row, msg, ATTR_WARN);
|
||||||
(rec.reserved == TRUNC_LINES)
|
|
||||||
? "*** Line limit reached - document truncated ***"
|
|
||||||
: "*** Content cache exhausted - document truncated ***",
|
|
||||||
ATTR_WARN);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user