Files
snark13 9f8aa6fc28 libc: две версии библиотеки — sprinter.lib (fast) / sprinter_safe.lib
Симметрично libbgi (bgi256/bgi256_safe): fast = -DLIBC_NOCHECK,
дефолт sprinter-cc; safe линкуется по --safe (флаг уже существовал).

Под LIBC_NOCHECK вырезаны ТОЛЬКО параметр-валидации:
- fgetc/fputc: NULL-check в горячей asm-обёртке (~11Т на каждый байт);
- fgets/fputs/fread/fwrite: NULL ptr/fp и EBADF на неверное направление
  потока; ftell/fseek/ungetc/fclose: NULL fp; cputs: NULL s.
НЕ тронуты: критичный _fd_guard (9-й OPEN вешает DSS — в обеих
версиях), функциональная маршрутизация (консоль/направление/hold),
cold-path валидации (fopen/cbl_open/irq/settextmode — экономии ноль).

libc/Makefile — dual-build по образцу libbgi (build/fast + build/safe,
общий стейл-контроль).  Корневой Makefile: в TESTS добавлены bgitest,
bgi_img, accfill, cblstream — раньше не собирались корневым make и
выпадали из size-check при чистой пересборке.

Дельты fast vs старая (safe-семантика): filetest -481, fbench -384,
solidt -180, errno -71, остальные -3..-9; роста нет.  Проверено в MAME:
filetest fast и safe (--safe, sprinter_safe.lib) — прогоны идентичны.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 22:11:01 +03:00

32 lines
967 B
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* ftell — логическая позиция потока. Без побочных эффектов: позиция
* fd корректируется на состояние буфера арифметикой —
* режим записи: fd_pos + level (несброшенный хвост впереди fd);
* режим чтения: fd_pos level (1, если hold от ungetc).
* Для консольных псевдопотоков — EBADF/-1.
*/
#include <unistd.h>
#include <errno.h>
#include "_file.h"
long ftell(FILE *fp)
{
#ifndef LIBC_NOCHECK
if (!fp) { errno = EBADF; return -1L; }
#endif
if (fp->flags & (_F_CONIN | _F_CONOUT)) {
errno = EBADF;
return -1L;
}
long pos = lseek(fp->fd, 0L, SEEK_CUR);
if (pos < 0) return -1L;
if (fp->flags & _F_DIROUT) {
pos += fp->level;
} else {
pos -= fp->level;
if (fp->hold != EOF) pos--;
}
return pos;
}