Two gaps the raylib examples hit.
The layout check compared a Flan enum against the header's `int` and
called it a disagreement. It is not one: Shim.cty lowers a defenum to
int32_t in a struct field exactly as it does in a parameter, which is
what the signature check already knew and the layout check did not. One
predicate now serves both, symmetric, and tolerant of a 32-bit integer
and nothing else -- f64 against the library's float still fails, in the
very struct whose other field is an enum. Camera3D.projection is a
CameraProjection again and rl/camera-projection is gone with it, so
`.projection :perspective` resolves at the construction site.
And generate-c's claim said nothing about a defconst or a defenum
member, so a wrong flag bit was completely silent. `bindings` gained
`enum`, `const` and `constant` lines saying what a Flan constant is
called in C -- the prefix is nowhere in the Flan name, so it is declared
rather than guessed. Nothing goes quiet in either direction: a name the
rule builds and the header lacks is reported, a rule that reaches
nothing is reported, and a defenum with no line is itself a finding,
because otherwise the silence just moves up one level.
clang's dump gives anonymous EnumDecls for every raylib enum and no
value at all for an enumerator written without `= n`, so the constants
are one flat table and the values are counted the way C counts them.
cache_format bumped with the dump type.
core-2d-camera, core-scissor-test, core-window-flags, core-world-screen
and core-window-should-close, ported from raylib 5.5's examples/core.
What each one asked of vendor/raylib:
2d-camera nothing. A whole Camera2D by value, per frame, into the
call that actually draws with it — the layout the
acceptance table pins through arithmetic, now going
through the path it was bound for.
scissor-test begin-scissor-mode / end-scissor-mode, hand-written.
window-flags twelve more ConfigFlags constants; raylib.flan carried
the four sand.flan sets and this reads eleven.
world-screen the 3D surface did not exist: no Vector3, no Camera3D,
and the importer refused every 3D function in raylib.h
by name for want of them. Two defstructs, two defenums,
begin/end-mode-3d, update-camera, get-world-to-screen,
draw-cube, draw-cube-wires, draw-grid — and 24 more 3D
lines the importer can generate now that the types are
described.
window-should-close set-exit-key, and Key/null to pass it.
The hand-written/generated line, written down in vendor/raylib/bindings:
a drawing pair inside a frame is hand-written, and so is anything whose
Flan face is not the C signature — set-exit-key takes a Key, update-camera
takes a (Ptr Camera3D) and a CameraMode. The window-state family and
get-mouse-x/y stay generated: plain scalars in and bool out, with nothing
for a hand-written line to add.
Camera3D's projection field stays i32, because the header says int and the
layout check holds this file to that; rl/camera-projection is the
conversion, and still takes a keyword.
generated.flan carries the 253 declarations the importer reads out of raylib's
header, so a build needs libraylib linkable and no header at all. The opt-in
no longer decides how many bindings a package has — every build now gets all
425, they are greppable, and they diff when raylib moves.
What that gives up is the build-time check, so `flan generate-c` is the only
thing that writes the file and it compares first: every defstruct against the
header's record, every hand-written declare-c against the header's signature,
and it writes nothing when they disagree. Against the 5.1-dev header on this
machine that is ten real differences and no write.
The 172 hand-written lines stay, and not out of caution. Everything the
generator emits agrees with the header by construction, so diffing generated
output against its own source is a tautology; the hand-written lines were
transcribed by a person, so they are the only thing here a header can
contradict. All ten of those differences came from them.
`bindings` beside `headers` is what survives regeneration, because a hand-edit
to a committed generated file does not. Two directives: `exclude` drops
raylib's three allocator entry points, and `name` gives the 19 generated
predicates the `?` spelling the hand-written ones already use.