diff --git a/README.md b/README.md index 946be37..52c0b93 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,13 @@ required capability. scripts and programs that rely on long-standing glibc behavior. 5. *(default)* — **vlibc**: glibc-extended, without the spoofing layer, but with extended standard features and high glibc compatibility. +- **Profiles 1-3 are functional.** `--enable-onlyposix`, `--enable-muslmimic`, + and `--enable-muslext` build with real build-time profile gating: a generated + `include/vlibc/features.h` exposes `VLIBC_LEVEL`, the public `` and + `` headers are gated by it, and an initial string slice (`memcpy`, + `memmove`, `memset`, `strlen`, `strcmp`, `strlcpy`, `strlcat`, + `strcasestr`) is compiled per level. Profiles 4 and 5 (`spoof`, `vlibc`) + remain configure-level declarations in this increment. - **Two install methods** (`--with-install=`): - `alongside` (default) — install next to the system libc, under a vlibc-specific tree; the system libc is left untouched. diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md index 8b5c852..008cb52 100644 --- a/STYLEGUIDE.md +++ b/STYLEGUIDE.md @@ -76,6 +76,34 @@ linked binaries (see `docs/overview.md`): Every public function carries the tightest correct attribute. +## Profile gating + +Profile-gated code follows these formatting and naming conventions (the +semantic classification of functions into levels lives in +`docs/compatibility.md`, not here): + +- Public headers gate declarations with `#if VLIBC_LEVEL >= N`. Prefer the + `VLIBC_LEVEL_GE(n)` helper from `include/vlibc/features.h`; fall back to the + raw comparison only when the level is a literal constant: + + ```c + #if VLIBC_LEVEL_GE(2) + size_t strlcpy(char *dst, const char *src, size_t n); + #endif + ``` + +- Group implementation sources by level in `Makefile.am` using the per-level + conditionals `if PROFILE_GE_2` / `if PROFILE_GE_3`, mirroring the + `#if VLIBC_LEVEL >= N` rule in headers. +- Standard headers use `VLIBC_`-prefixed include guards + (`VLIBC_STDDEF_H`, `VLIBC_STRING_H`), never the `_STDDEF_H`-style reserved + forms. A leading underscore is reserved for the implementation and the + C/POSIX standards (see Naming); the `VLIBC_` prefix stays out of the + reserved namespace while remaining unambiguous. +- Intent attributes respect the gating: `pure` / `const` are only valid on + side-effect-free functions. Never annotate a mutating function (`memcpy`, + `memmove`, `memset`, `strlcpy`, `strlcat`) with either. + ## Error handling - No empty blocks; no silent failure. diff --git a/docs/compatibility.md b/docs/compatibility.md index 80af717..66e4ae6 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -11,6 +11,51 @@ mutually exclusive; the default is `vlibc`. | 4 | `--enable-spoof` | `spoof` | A glibc replica: emulates glibc for drop-in compatibility, higher than `muslext` or `vlibc` full. | | 5 | *(default)* | `vlibc` | glibc-extended: glibc minus its baggage, plus extended standard features. High (but not spoof-level) glibc compatibility. | +## Profile mechanism + +The profiles map onto a single integer level, `VLIBC_LEVEL`. Levels are +**cumulative**: a profile at level N exposes everything whose minimum level is +`<= N`. + +| Level | Classification | +|-------|-----------------------------------------| +| 1 | ISO C + POSIX base | +| 2 | + BSD / XSI extensions | +| 3 | + GNU extensions | + +Public headers gate declarations with `#if VLIBC_LEVEL >= N`; a function whose +minimum level is 2 is only declared when the active profile is level 2 or +higher. The build applies the same rule to sources via +`AM_CONDITIONAL([PROFILE_GE_2])` and `AM_CONDITIONAL([PROFILE_GE_3])`, so each +level's implementation files are only compiled when the selected profile +reaches that level. + +The generated installed header `include/vlibc/features.h` exposes the macros +the gating is based on: + +- `VLIBC_LEVEL` — the active profile's integer level. +- `VLIBC_PROFILE` — the selected profile name. +- `VLIBC_LEVEL_GE(n)` — expands to 1 when `VLIBC_LEVEL >= n`, 0 otherwise. + +### Slice manifest + +The initial implementation covers eight string/memory functions, classified as +follows: + +| Function | Level | Origin | +|--------------|-------|---------| +| `memcpy` | L1 | ISO C | +| `memmove` | L1 | ISO C | +| `memset` | L1 | ISO C | +| `strlen` | L1 | ISO C | +| `strcmp` | L1 | ISO C | +| `strlcpy` | L2 | BSD | +| `strlcat` | L2 | BSD | +| `strcasestr` | L3 | GNU | + +Profiles 4 and 5 (`spoof`, `vlibc`) build on the same level mechanism but are +not implemented in this increment beyond their configure declarations. + ## Differences from glibc - **No legacy baggage.** vlibc targets modern, standard-conforming behavior and