flan/test/headers/sample.h
Joseph Ferano 1fb208a991 The header is checked at build time, not only by a tool
Reading the header produced declarations and nothing else, so the gap the whole
thing exists to close — that nothing verifies a declaration against the library
— was closed by a command somebody could run rather than by a property the
build had. Now `import` runs both comparisons whenever a header resolves.

Build-stopping, not a note. The package named the header, so the header is the
package's own claim about what it binds; a defstruct that disagrees lays fields
out in the wrong order and reads as five plausible numbers rather than as a
link error. Continuing past a known-wrong layout to produce a program that will
read garbage is the shape the house rule against swallowing things exists to
prevent. Both messages point at the line in raylib.flan, not at the header.

Verified by breaking it on purpose: a permuted Texture2D stops the build naming
the field that moved, and `f64` where raylib says `float` stops it naming the
parameter — which is the hazard BUILT.md calls out by name and says only a test
can catch.

A set-but-wrong FLAN_RAYLIB_H used to be indistinguishable from not opting in:
the line was skipped and nothing was said. Unset still means off and silent; a
path that is not there is now an error naming it. That is the difference
between an opt-in and a trap.

test/headers/sample.h is one function per decision the importer makes. The
raylib case needs raylib installed, at the right version, with a variable set,
so it would skip everywhere and cover nothing; this one does not move. It also
found a bug, fixed next.

Reach still prunes with 256 extra declarations in play: a wasm32-wasi build of
a program that imports raylib and calls none of it links without libraylib,
which is the case Reach.link exists for.
2026-09-12 16:03:07 +07:00

49 lines
2.3 KiB
C

/* A small C header, for testing the importer against something that does not
* move. The raylib case needs raylib installed, needs the right version of it,
* and needs an environment variable set, so it is the wrong thing to hang the
* refusal catalogue on: it would skip everywhere and cover nothing. This
* header has one function per decision Cimport makes, and the test asserts on
* the reasons rather than on the count.
*
* Deliberately includes nothing. A header that pulls in stdio would make the
* dump thirty times larger and would put libc's declarations in the way of
* reading the test's. */
typedef struct Pair { float x; float y; } Pair;
typedef struct Shade { unsigned char r, g, b, a; } Shade;
typedef struct Undescribed { int a; int b; } Undescribed;
/* A second typedef name for a record the package already describes under
* another one. raylib does this: struct Texture is Texture2D and also
* TextureCubemap. Both have to resolve to the one defstruct. */
typedef struct Pair Point;
typedef enum Mood { MOOD_CALM = 0, MOOD_CROSS = 1 } Mood;
typedef void (*Notify)(void *user, unsigned int n);
/* --- accepted --- */
void set_seed(unsigned int seed);
int add_ints(int a, int b);
Pair make_pair(float x, float y); /* aggregate out, by out-pointer */
float pair_len(Pair p); /* aggregate in, by pointer */
Shade tint(Shade base, Shade over);
int name_length(const char *text); /* const char * is a string in */
int count_at(const int *values, int n); /* T * is (Ptr T) */
Pair point_of(Point p); /* the second typedef name */
int mood_value(Mood m); /* a C enum is an int */
void take_nothing(void);
/* --- refused, one per reason --- */
const char *name_of(int which); /* returns char * */
void fill_buffer(char *out, int cap); /* non-const char *: C writes it */
int printf_like(const char *fmt, ...); /* variadic */
void on_event(Notify cb); /* a callback */
long file_time(const char *path); /* long varies across our targets */
Undescribed make_undescribed(void); /* no defstruct for it */
/* Two names that kebab to one, so the collision is refused by name rather than
* arriving at the checker as a duplicate declaration nobody wrote. */
int Spin2D(int n);
int spin2d(int n);