# Заголовки libc: контракт затенения SDCC (2026-07-06)

`libc/include` стоит в -I ПЕРЕД заголовками SDCC, поэтому наш файл с
именем стандартного заголовка «затеняет» SDCC-шный.  Два разрешённых
паттерна:

## 1. Цепочка `#include_next` — только ДОБАВЛЯЕМ

Наш заголовок первым делом делает `#include_next <имя>` (берёт
SDCC-версию) и дальше только добавляет Sprinter-расширения.  Ничего
из стандартной части не переобъявлять — malloc/strlen/… должны
приходить из SDCC, иначе разъедутся прототипы с z80.lib (уже кусало:
полный shadow stdlib.h терял malloc/free).

| Заголовок | Что добавляем |
|---|---|
| `stdlib.h` | min/max (функции, int16_t — как `int min()` в Solid-C) |
| `string.h` | strlwr/strupr (CP866-регистры) |

## 2. Полная замена — обязаны продублировать контракт SDCC

Наш заголовок полностью замещает SDCC-шный.  Он ОБЯЗАН объявить всё,
что программы берут из z80.lib, с точными SDCC-сигнатурами:

| Заголовок | Обязан объявлять (из z80.lib) | Наше |
|---|---|---|
| `stdio.h` | printf, sprintf, vprintf, vsprintf | FILE* API (буферизованный B+), puts/putchar/getchar (наши, ESTEX), scanf-семейство, dec*/hex*, gets |
| `time.h` | struct tm, time_t, time, mktime, gmtime, localtime, asctime, ctime — **раскладка struct tm и __TIME_UNSIGNED=1 должны совпадать с SDCC ABI** (см. шапку time.h) | datetime_t, getdatetime/setdatetime, DOW_* |

При апгрейде SDCC сверять сигнатуры этих двух заголовков с
`third_party/sdcc/share/sdcc/include/`.

## 3. Свои заголовки (SDCC-аналога нет — затенения нет)

conio.h, dir.h, dos.h, errno.h, fcntl.h, mouse.h, palette.h,
sprinter*.h, unistd.h, bios/*.

Графика вынесена из libc в отдельную библиотеку libbgi/: её публичные
заголовки gfx.h (mode-agnostic BGI_GFX) и graphics.h (BGI API) живут в
libbgi/include/ и пробрасываются через -I libbgi/include (sprinter-cc
добавляет его автоматически).  Внутренний заголовок графики —
libbgi/_bgi.h (слияние старых libc/gfx/_gfx.h и libc/bgi/_bgi.h).

## Правила

- новый стандартный заголовок — сначала пробовать паттерн 1
  (include_next); паттерн 2 — только если надо переопределить
  реализацию (как puts/putchar на ESTEX);
- в заголовках паттерна 2 — комментарий, какие декларации обслуживают
  z80.lib;
- internal-заголовки libc (`_conio.h`, `_file.h`, …) живут
  РЯДОМ с исходниками в libc/<area>/, не в libc/include.  Internal
  графики — в libbgi/_bgi.h (корень libbgi/, подключается из common/ и
  bgi256/bgi16/ как `#include "../_bgi.h"`).
