2 Commits

Author SHA1 Message Date
55d986c631 Drop the TODO.md section numbers from 26 files
All checks were successful
libakstdlib CI Build / cmake_build (push) Successful in 5m53s
libakstdlib CI Build / sanitizers (push) Successful in 2m55s
libakstdlib CI Build / coverage (push) Successful in 2m48s
libakstdlib CI Build / mutation_test (push) Successful in 12m39s
Eighty-five comments cited section numbers -- 1.1, 2.2.6, 3.6 -- from a
numbering the file had already abandoned before the move to the tracker. They
label completed work, so the pointer was the only wrong part.

The citation is removed and the sentence kept, which is what issue #27
recommended: these are labels, not references, and a label carrying a
version-dependent pointer goes stale again at the next reorganisation. Where a
pointer earns its place it names what actually holds the content now --
UPGRADING.md for the confirmed defects, libakerror #15 for the target
namespacing, issue #7 for the mutation survivors.

README.md and akstdlib.h sent readers to TODO.md for 'what is still open';
they name the tracker.

Verified: cmake --build build && ctest --test-dir build, 19/19.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Andrew Kesterson <andrew@aklabs.net>
2026-08-02 22:01:27 -04:00
024fe6cde2 Version the library at 0.1.0
project() now carries VERSION 0.1.0, and is the single place a version number
is spelled. It flows into generated version macros, the shared library's
VERSION/SOVERSION, the Version: field in akstdlib.pc, and a new
akstdlibConfigVersion.cmake. Before this @PROJECT_VERSION@ expanded to
nothing, so akstdlib.pc shipped an empty Version: and libakstdlib.so carried
no soname at all.

0.x on purpose: TODO.md section 2.1 still records four confirmed defects whose
fixes change documented behaviour, so the API is not being promised yet. While
the major version is 0 the soname carries MAJOR.MINOR -- 0.1 and 0.2 are
different ABIs -- and becomes MAJOR alone at 1.0. The if() in CMakeLists.txt
and the #if in tests/test_version.c encode that rule and are tested against
each other.

include/akstdlib_version.h.in is configured into the build tree as
akstdlib_version.h and installed beside akstdlib.h. It defines
AKSL_VERSION_MAJOR/MINOR/PATCH/STRING/NUMBER and AKSL_VERSION_SONAME.
AKSL_VERSION_NUMBER is computed rather than written as a literal, because a
literal 000100 is octal in C and would make 0.1.0 compare as 64;
test_version.c asserts it against the runtime components, so a rewrite to a
literal fails.

Those macros record what a caller was compiled against. aksl_version(),
aksl_version_string() and aksl_version_soname() report what actually loaded,
and AKSL_VERSION_CHECK() compares the two, raising AKERR_VALUE naming both.
It is a macro so that it expands at the caller's site and captures the
caller's numbers; the function compares them against the ones baked into the
library. Compatibility is "same soname", so patch is ignored -- a caller built
against 0.1.0 keeps working against 0.1.7.

Normally the soname catches a mismatch at load time and the check never fires.
It earns its keep when the soname is bypassed: a 0.2.0 build dropped in under
the 0.1 filename loads happily, and only the check notices.

write_basic_package_version_file() uses SameMinorVersion to mirror the soname,
falling back to ExactVersion below CMake 3.11 where that mode does not exist.
The fallback is stricter than the soname rule -- it pins the patch level too --
but never laxer, and wrongly refusing a good pairing beats wrongly accepting a
bad one.

Coverage of src/stdlib.c rose to 99.1% of lines (217/219), 45.1% of branches
and 25/25 functions. That puts branch coverage back over the old 45 gate, but
the gate stays at 40: 0.1 points of headroom is not a ratchet.

ctest 14/14, ASan+UBSan 14/14, coverage 16/16 at 90/40. Also verified out of
tree: SONAME libakstdlib.so.0.1 recorded in consumers, pkg-config
--modversion reporting 0.1.0, find_package(akstdlib 0.1) accepted with 0.2 and
1.0 refused, a patch-bumped 0.1.1 loading and passing the check, a 0.2.0
dropped in under the 0.1 filename caught by it, and an embedded
add_subdirectory build keeping its own version rather than the parent's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Andrew Kesterson <andrew@aklabs.net>
2026-07-30 22:40:49 -04:00