Take libakerror 2.0.2, libakstdlib and libakgl 0.9.0 #59

Open
tachikoma wants to merge 2 commits from deps-update into main
Collaborator

Bumps deps/libakerror, deps/libakstdlib and deps/libakgl to their current main, applies what their upgrade notes require, retires the two workarounds they make obsolete, and unbreaks three example programs that were already broken on main.

Two commits, split by cause: what the bump changed, and what the bump revealed.


1. The bump

libakerror 2.0.1 → 2.0.2 (63 commits)

Two of its fixes were this repository's own filed issues, and both workarounds are deleted:

Was Now
libakerror namespaced mutation when embedded but not coverage, so a coverage build collided on the bare name — worked around by shadowing add_custom_target() It applies the same CMAKE_SOURCE_DIR test to both (its #15, closed). The shadow could only ever fire on a name the dependency has stopped using, so it is gone rather than left as dead code
No akerrorConfigVersion.cmake, so no consumer could request a version floor. MAINTENANCE.md said to add a 1.0 floor to our find_dependency calls when it landed It installs one at SameMajorVersion (its #16, closed). The floor is now 2.0, and this repository has no find_dependency calls — it reaches every dependency by add_subdirectory. That paragraph now says so instead of carrying an instruction nobody can follow

A measured cost. IGNORE's context changed shape: __akerr_last_ignored was an extern pointer and is now a per-TU static akerr_last_ignored holding a copy, so the pool slot can be released — a real leak fix. Nothing here referenced the symbol, but because it is static in a public header, every translation unit gets one:

TLS segment of build/basic
libakerror 2.0.1 none at all
libakerror 2.0.2 1,417,248 bytes — 1.35 MiB, per thread

38 copies × 37,296 accounts for the segment exactly. Plus 84 -Wunused-variable warnings, one per TU that includes the header without using IGNORE. Filed upstream as libakerror #37 and recorded in MAINTENANCE.md, not patched here — patching a submodule forks it.

libakstdlib

Directory and file-metadata wrappers, with no version bump. aksl_snprintf keeps its int *count — an intermediate commit removed it and the merge put it back — but now reports the required length on truncation rather than 0. Every call site here reads it only after a successful return, so nothing moved.

The directory wrappers close the gap DIRECTORY was refused for (libakstdlib #10, closed). The verb is still unwritten so it still refuses, but it no longer blames a wrapper that exists — and tests/disk_verbs.c now asserts both halves, that it says "not implemented" and that it does not name libakstdlib. What writing it would need is #55.

libakgl → current main at 0.9.0

Registers libccd and tg as submodules. A tree that ran git submodule update --init --recursive before this bump needs it again, or the configure dies on a missing libccd/src/ccd/config.h.cmake.in.


2. What the bump revealed

None of this was caused by the bump. It was found by running the tutorial games, which nothing else does.

ae2c702 ("Add native RND and ASC functions") made RND a function name, and a suffixed identifier that collides with one is refused. Three example programs held their PRNG output in RND#, or a host field in RND%, and none had run since:

  • examples/galaga/RND% on both ENEMY and GAME, now ROLL%. The C member stays rnd. This one was caughtexample_galaga and example_galaga_interop have been failing.
  • examples/breakout/characters/breakout.bas and examples/megademo/megademo.basRND#ROLL#. Neither is in any test, so neither failure was visible.

examples/breakout/sprites/breakout.bas was broken a second, independent way: seven REM lines the reader refuses. Worth knowing the ceiling is not the one the message namessrc/sink_stdio.c fails when the read filled the buffer without seeing a terminator, so with AKBASIC_MAX_LINE_LENGTH at 80 the message says "79 character limit" and the real maximum is 78, because a 79-character line leaves no room for the \n. The sweeps that fixed the corpus and the megademo for this never reached this file.

The prose went stale with the code. Chapter 21 said "there is no RND verb in this dialect; issue #16 tracks adding one"; chapter 17's historical aside offered an LCG that no longer parses; four REM blocks said the same. All corrected — and they now say why these programs keep their own generator anyway: the sequence has to be reproducible for a headless run to be the same game on every machine, which is what lets interop_test.c assert exact counts. Chapter 21 also gains the rule that bit them, since a reader writing a host type will hit it.


Verification

Before After
default 113/114 — docs_examples failing 114/114
-DAKBASIC_WITH_AKGL=ON 113/116 — example_galaga, example_galaga_interop, docs_examples failing 116/116

docs_examples green in both. All three tutorial games run clean under the dummy drivers. Verified from a scratch build tree, not an incremental one. akgl_typing skips — no xdotool on this machine.

The DIRECTORY change was mutation-checked per MAINTENANCE.md: reverting the message by file copy makes disk_verbs fail, restoring it makes it pass.

Filed rather than fixed

  • libakerror #37 — the 1.35 MiB TLS regression and the 84 warnings
  • libakerror #38UPGRADING.md documents a 2.0.3 that project() never stamped, which is why the version tables here read 2.0.2
  • libakstdlib #5 — commented: fixed in the other repository, and the floor it names is now wrong twice over
  • #55DIRECTORY is unblocked and can be written
  • #56 — the Doxygen gate fails on main: nine errors, four distinct defects, none of them new and none in files this branch touches
  • #58 — the three example programs are in no test, which is why they rotted

#56 is worth a look before merging this. It is pre-existing and out of scope here, but MAINTENANCE.md calls the documentation a gate and it is currently red.

Co-Authored-By: Andrew Kesterson andrew@aklabs.net
Co-Authored-By: Claude Code (Claude Opus 5, claude-opus-5[1m]) noreply@anthropic.com

Bumps `deps/libakerror`, `deps/libakstdlib` and `deps/libakgl` to their current `main`, applies what their upgrade notes require, retires the two workarounds they make obsolete, and unbreaks three example programs that were already broken on `main`. Two commits, split by cause: **what the bump changed**, and **what the bump revealed**. --- ## 1. The bump ### libakerror 2.0.1 → 2.0.2 (63 commits) Two of its fixes were this repository's own filed issues, and both workarounds are deleted: | Was | Now | |---|---| | `libakerror` namespaced `mutation` when embedded but not `coverage`, so a coverage build collided on the bare name — worked around by shadowing `add_custom_target()` | It applies the same `CMAKE_SOURCE_DIR` test to both (its **#15**, closed). The shadow could only ever fire on a name the dependency has stopped using, so it is gone rather than left as dead code | | No `akerrorConfigVersion.cmake`, so no consumer could request a version floor. `MAINTENANCE.md` said to add a `1.0` floor to our `find_dependency` calls when it landed | It installs one at `SameMajorVersion` (its **#16**, closed). The floor is now **`2.0`**, and this repository has **no `find_dependency` calls** — it reaches every dependency by `add_subdirectory`. That paragraph now says so instead of carrying an instruction nobody can follow | **A measured cost.** `IGNORE`'s context changed shape: `__akerr_last_ignored` was an `extern` pointer and is now a per-TU `static akerr_last_ignored` holding a *copy*, so the pool slot can be released — a real leak fix. Nothing here referenced the symbol, but because it is `static` in a public header, every translation unit gets one: | | TLS segment of `build/basic` | |---|---| | libakerror 2.0.1 | none at all | | libakerror 2.0.2 | **1,417,248 bytes — 1.35 MiB, per thread** | 38 copies × 37,296 accounts for the segment exactly. Plus 84 `-Wunused-variable` warnings, one per TU that includes the header without using `IGNORE`. **Filed upstream as libakerror #37 and recorded in `MAINTENANCE.md`, not patched here** — patching a submodule forks it. ### libakstdlib Directory and file-metadata wrappers, with no version bump. `aksl_snprintf` **keeps** its `int *count` — an intermediate commit removed it and the merge put it back — but now reports the *required* length on truncation rather than 0. Every call site here reads it only after a successful return, so nothing moved. The directory wrappers close the gap `DIRECTORY` was refused for (libakstdlib **#10**, closed). The verb is still unwritten so it still refuses, but it no longer blames a wrapper that exists — and `tests/disk_verbs.c` now asserts both halves, that it says "not implemented" and that it does **not** name `libakstdlib`. What writing it would need is **#55**. ### libakgl → current `main` at 0.9.0 Registers `libccd` and `tg` as submodules. **A tree that ran `git submodule update --init --recursive` before this bump needs it again**, or the configure dies on a missing `libccd/src/ccd/config.h.cmake.in`. --- ## 2. What the bump revealed None of this was caused by the bump. It was found by running the tutorial games, which nothing else does. `ae2c702` ("Add native RND and ASC functions") made `RND` a function name, and a suffixed identifier that collides with one is refused. **Three example programs held their PRNG output in `RND#`, or a host field in `RND%`, and none had run since:** - `examples/galaga/` — `RND%` on both `ENEMY` and `GAME`, now `ROLL%`. The C member stays `rnd`. **This one was caught** — `example_galaga` and `example_galaga_interop` have been failing. - `examples/breakout/characters/breakout.bas` and `examples/megademo/megademo.bas` — `RND#` → `ROLL#`. **Neither is in any test**, so neither failure was visible. `examples/breakout/sprites/breakout.bas` was broken a second, independent way: seven `REM` lines the reader refuses. Worth knowing the ceiling is **not the one the message names** — `src/sink_stdio.c` fails when the read filled the buffer without seeing a terminator, so with `AKBASIC_MAX_LINE_LENGTH` at 80 the message says *"79 character limit"* and the real maximum is **78**, because a 79-character line leaves no room for the `\n`. The sweeps that fixed the corpus and the megademo for this never reached this file. **The prose went stale with the code.** Chapter 21 said *"there is no RND verb in this dialect; issue #16 tracks adding one"*; chapter 17's historical aside offered an LCG that no longer parses; four `REM` blocks said the same. All corrected — and they now say *why* these programs keep their own generator anyway: the sequence has to be reproducible for a headless run to be the same game on every machine, which is what lets `interop_test.c` assert exact counts. Chapter 21 also gains the rule that bit them, since a reader writing a host type will hit it. --- ## Verification | | Before | After | |---|---|---| | default | 113/114 — `docs_examples` failing | **114/114** | | `-DAKBASIC_WITH_AKGL=ON` | 113/116 — `example_galaga`, `example_galaga_interop`, `docs_examples` failing | **116/116** | `docs_examples` green in both. All three tutorial games run clean under the dummy drivers. Verified from a scratch build tree, not an incremental one. `akgl_typing` skips — no `xdotool` on this machine. The `DIRECTORY` change was mutation-checked per `MAINTENANCE.md`: reverting the message by file copy makes `disk_verbs` fail, restoring it makes it pass. ## Filed rather than fixed - **libakerror #37** — the 1.35 MiB TLS regression and the 84 warnings - **libakerror #38** — `UPGRADING.md` documents a 2.0.3 that `project()` never stamped, which is why the version tables here read **2.0.2** - **libakstdlib #5** — commented: fixed in the other repository, and the floor it names is now wrong twice over - **#55** — `DIRECTORY` is unblocked and can be written - **#56** — the Doxygen gate fails on `main`: nine errors, four distinct defects, none of them new and none in files this branch touches - **#58** — the three example programs are in no test, which is why they rotted **#56 is worth a look before merging this.** It is pre-existing and out of scope here, but `MAINTENANCE.md` calls the documentation a gate and it is currently red. Co-Authored-By: Andrew Kesterson <andrew@aklabs.net> Co-Authored-By: Claude Code (Claude Opus 5, claude-opus-5[1m]) <noreply@anthropic.com>
tachikoma added 2 commits 2026-08-05 23:28:56 -04:00
Bumps all three ak* submodules to their current main, applies what their
upgrade notes require, and retires the two workarounds they make obsolete.

libakerror 2.0.1 -> 2.0.2 (63 commits). Two of its fixes were this
repository's own filed issues, and both workarounds are gone:

  - It namespaces its embedded `coverage` target now, the same
    CMAKE_SOURCE_DIR test it already applied to `mutation` (its issue #15).
    The add_custom_target() shadow that renamed it on the way past could
    only ever fire on a name the dependency has stopped using, so it is
    deleted rather than left as dead code.
  - It installs akerrorConfigVersion.cmake at SameMajorVersion (its issue
    #16). MAINTENANCE.md said to add a `1.0` floor to our find_dependency
    calls when this landed; the floor is now `2.0`, and we have no
    find_dependency calls to add it to, so the paragraph says that instead
    of an instruction nobody can follow.

Its IGNORE context also changed shape: `__akerr_last_ignored` was an extern
pointer, and is now a per-translation-unit `static akerr_last_ignored` holding
a copy, so the pool slot can be released. Nothing here referenced the symbol,
but it costs us 1.35 MiB of thread-local storage -- 38 TUs x 37,296 bytes,
measured as the entire TLS segment of build/basic, where 2.0.1 produced no TLS
segment at all -- plus 84 -Wunused-variable warnings. Filed upstream as
libakerror issue #37 and recorded in MAINTENANCE.md rather than patched here,
because patching a submodule forks it.

libakstdlib gains directory and file-metadata wrappers with no version bump.
aksl_snprintf keeps its `int *count` -- an intermediate commit removed it and
the merge put it back -- but now reports the required length on truncation
rather than 0. Every call site here reads it only after a successful return,
so nothing moved.

The directory wrappers close the gap DIRECTORY was refused for (libakstdlib
issue #10). The verb is still unwritten, so it still refuses, but it no longer
blames a wrapper that exists: the message is "DIRECTORY is not implemented
yet" and tests/disk_verbs.c asserts both that it says so and that it does not
name libakstdlib. What writing it would need is akbasic issue #55.

libakgl moves to the current main at 0.9.0. It registers libccd and tg as
submodules, so a tree that only ran `git submodule update --init --recursive`
before the bump needs it again or the configure fails on a missing
libccd/src/ccd/config.h.cmake.in.

Verified: 114/114 default, 116/116 under -DAKBASIC_WITH_AKGL=ON, docs_examples
green in both. libakerror's UPGRADING.md documents a 2.0.3 that project()
never stamped, so the version tables read 2.0.2 -- libakerror issue #38.

Co-Authored-By: Andrew Kesterson <andrew@aklabs.net>
Co-Authored-By: Claude Code (Claude Opus 5, claude-opus-5[1m]) <noreply@anthropic.com>
Unbreak the three example programs the RND merge left behind
All checks were successful
akbasic CI Build / cmake_build (push) Successful in 3m46s
akbasic CI Build / coverage (push) Successful in 4m16s
akbasic CI Build / sanitizers (push) Successful in 8m10s
akbasic CI Build / akgl_build (push) Successful in 8m10s
akbasic CI Build / mutation_test (push) Successful in 17m55s
13f1df03ef
Adding native RND and ASC (ae2c702) made RND a function name, and a suffixed
identifier that collides with one is refused -- "SYNTAX ERROR Reserved word in
variable name". Three example programs held their PRNG output in a variable
called RND#, or a host field called RND%, and none of them had run since:

  - examples/galaga/ bound RND% as a host field on both ENEMY and GAME. The
    BASIC-visible name is ROLL% now; the C member stays `rnd`. This one was
    caught by example_galaga and example_galaga_interop, which have been
    failing.
  - examples/breakout/characters/breakout.bas and examples/megademo/
    megademo.bas both use RND# for their LCG output, renamed to ROLL#. Neither
    is in any test, so neither failure was visible.

examples/breakout/sprites/breakout.bas was broken a second way: seven REM lines
the reader refuses. Worth recording that the ceiling is not the one the message
names -- src/sink_stdio.c fails when the read filled the buffer without seeing
a terminator, so with AKBASIC_MAX_LINE_LENGTH at 80 the message says "79
character limit" and the real maximum is 78, because a 79-character line leaves
no room for the newline. The sweeps that fixed the corpus and the megademo for
this did not reach this file. The seven comments are reflowed.

The prose went stale with the code. Chapter 21 said "there is no RND verb in
this dialect; issue #16 tracks adding one", chapter 17's historical aside
offered an LCG that no longer parses, and four REM blocks across the two games
said the same thing. All of them now say RND exists, and say why these programs
keep their own generator anyway: the sequence has to be reproducible for a
headless run to be the same game on every machine, which is what lets
interop_test.c assert exact counts.

Chapter 21 also gains the rule that bit them, since a reader writing a host
type will hit it: a host field name is a bare word and shares a namespace with
every verb and function.

None of this came from the submodule bump -- all three were already broken on
main. It was found by running the tutorial games, which nothing else does;
that gap is akbasic issue #58.

Verified: all three run clean under the dummy drivers, and 114/114 default,
116/116 with akgl.

Co-Authored-By: Andrew Kesterson <andrew@aklabs.net>
Co-Authored-By: Claude Code (Claude Opus 5, claude-opus-5[1m]) <noreply@anthropic.com>
All checks were successful
akbasic CI Build / cmake_build (push) Successful in 3m46s
Required
Details
akbasic CI Build / coverage (push) Successful in 4m16s
Required
Details
akbasic CI Build / sanitizers (push) Successful in 8m10s
Required
Details
akbasic CI Build / akgl_build (push) Successful in 8m10s
Required
Details
akbasic CI Build / mutation_test (push) Successful in 17m55s
Required
Details
This pull request doesn't have enough required approvals yet. 0 of 1 approvals granted from users or teams on the allowlist.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin deps-update:deps-update
git checkout deps-update
Sign in to join this conversation.