11 Commits

Author SHA1 Message Date
acb47a0d56 Preserve required snprintf length on truncation
All checks were successful
libakstdlib CI Build / cmake_build (push) Successful in 2m55s
libakstdlib CI Build / sanitizers (push) Successful in 2m57s
libakstdlib CI Build / coverage (push) Successful in 2m46s
libakstdlib CI Build / mutation_test (push) Successful in 18m29s
2026-08-03 18:25:43 -04:00
0620370dd9 Remove unused snprintf count parameter
All checks were successful
libakstdlib CI Build / sanitizers (push) Successful in 3m3s
libakstdlib CI Build / cmake_build (push) Successful in 3m3s
libakstdlib CI Build / coverage (push) Successful in 5m12s
libakstdlib CI Build / mutation_test (push) Successful in 13m17s
2026-08-03 16:33:09 -04:00
83ff77608f Address directory wrapper review
All checks were successful
libakstdlib CI Build / cmake_build (push) Successful in 2m58s
libakstdlib CI Build / sanitizers (push) Successful in 2m57s
libakstdlib CI Build / coverage (push) Successful in 2m47s
libakstdlib CI Build / mutation_test (push) Successful in 13m26s
2026-08-03 15:00:56 -04:00
d5e5e95c61 Add directory stream wrappers
All checks were successful
libakstdlib CI Build / coverage (push) Successful in 2m47s
libakstdlib CI Build / sanitizers (push) Successful in 2m54s
libakstdlib CI Build / cmake_build (push) Successful in 2m59s
libakstdlib CI Build / mutation_test (push) Successful in 12m31s
2026-08-03 13:45:59 -04:00
2b79aca103 Merge pull request 'Wrap file metadata calls' (#31) from 9 into main
All checks were successful
libakstdlib CI Build / sanitizers (push) Successful in 2m51s
libakstdlib CI Build / cmake_build (push) Successful in 2m55s
libakstdlib CI Build / coverage (push) Successful in 2m52s
libakstdlib CI Build / mutation_test (push) Successful in 12m4s
Reviewed-on: #31
2026-08-03 11:05:43 -04:00
15e9104d9e Test file metadata failure paths
All checks were successful
libakstdlib CI Build / coverage (push) Successful in 2m51s
libakstdlib CI Build / cmake_build (push) Successful in 2m59s
libakstdlib CI Build / sanitizers (push) Successful in 3m4s
libakstdlib CI Build / mutation_test (push) Successful in 12m14s
Co-authored-by: Andrew Kesterson <andrew@aklabs.net>
2026-08-03 10:43:47 -04:00
01034fc668 Document file metadata wrapper behavior
All checks were successful
libakstdlib CI Build / coverage (push) Successful in 2m44s
libakstdlib CI Build / cmake_build (push) Successful in 2m56s
libakstdlib CI Build / sanitizers (push) Successful in 3m1s
libakstdlib CI Build / mutation_test (push) Successful in 12m58s
Co-authored-by: Andrew Kesterson <andrew@aklabs.net>
2026-08-03 09:02:19 -04:00
8c94231167 Wrap file metadata calls
All checks were successful
libakstdlib CI Build / cmake_build (push) Successful in 3m2s
libakstdlib CI Build / sanitizers (push) Successful in 3m3s
libakstdlib CI Build / coverage (push) Successful in 3m1s
libakstdlib CI Build / mutation_test (push) Successful in 12m46s
Co-authored-by: Andrew Kesterson <andrew@aklabs.net>
2026-08-03 07:34:16 -04:00
be725f8cf2 Merge pull request 'Document libc wrapper contract' (#30) from 9 into main
All checks were successful
libakstdlib CI Build / cmake_build (push) Successful in 2m53s
libakstdlib CI Build / sanitizers (push) Successful in 3m3s
libakstdlib CI Build / coverage (push) Successful in 2m45s
libakstdlib CI Build / mutation_test (push) Successful in 11m59s
Reviewed-on: #30
2026-08-03 06:53:05 -04:00
58f426abce Document libc wrapper contract
All checks were successful
libakstdlib CI Build / coverage (push) Successful in 2m47s
libakstdlib CI Build / sanitizers (push) Successful in 2m57s
libakstdlib CI Build / cmake_build (push) Successful in 3m15s
libakstdlib CI Build / mutation_test (push) Successful in 12m35s
Co-authored-by: Andrew Kesterson <andrew@aklabs.net>
2026-08-03 06:38:21 -04:00
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
33 changed files with 787 additions and 142 deletions

View File

@@ -21,7 +21,7 @@ jobs:
# different libakerrors depending on where you built: the install went to
# /usr/local, while the build below is top-level and so compiles
# deps/libakerror at the pinned commit via add_subdirectory -- the
# installed one was never actually linked against. TODO.md 2.3.
# installed one was never actually linked against.
#
# The submodule wins. It is the version this repository pins, tests and
# ships against, and a CI that tests a different one is testing something
@@ -155,7 +155,7 @@ jobs:
# new surface being argument validation whose mutants are frequently
# equivalent. `errno = 0` deleted from a wrapper whose libc call always
# sets errno cannot be distinguished by any test that could be written.
# The survivors worth acting on are named in TODO.md; raise the gate as
# The survivors worth acting on are named in issue #7; raise the gate as
# they become assertions.
- name: mutation testing
run: |

View File

@@ -14,6 +14,7 @@ reasoning. The implementation is split by domain:
| `src/stdlib.c` | memory, formatted output, string-to-number, realpath, djb2, and the list/tree traversal entry points |
| `src/string.c` | the `string.h` surface |
| `src/stream.c` | `stdio.h` beyond open/read/write/close |
| `src/dir.c` | directory stream open/read/rewind/close |
| `src/collections.c` | list and tree operations, hash map, string buffer, FNV-1a |
| `src/aksl_internal.h` | shared internals; not installed, not public |
@@ -76,6 +77,10 @@ return convention and the `PREPARE_ERROR` / `FAIL_*` / `SUCCEED_RETURN` pattern.
Four conventions hold across the whole library, and a new wrapper that breaks one
of them is wrong even if it compiles and passes:
- **Preserve the libc contract unless there is a compelling, documented reason
not to.** libc behaviour is the standard to meet. This library changes only
the error transport (to `akerror`) and, where libc returns a value, the result
shape (through a caller-provided destination pointer).
- **A NULL out-param is a caller error**, not "don't care".
- **Finding nothing is success** -- searching functions write NULL or zero and
return NULL.
@@ -93,6 +98,11 @@ The build is `-Wall -Wextra` and CI adds `-Werror`. `-Wpedantic` is deliberately
off: libakerror's `FAIL_*` macros trip "ISO C99 requires at least one argument
for the ..." on their own expansion, not on anything at the call site.
**Do not wrap a libc function that cannot fail and provides no failure or
operation-status result.** There is no `akerror` context to carry. A value such
as `umask()`'s previous mask is not an operation-status result, so `umask()` is
not a wrapper candidate.
## Testing Guidelines
Add a new test by creating `tests/test_mything.c` and adding `mything` to the

View File

@@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.10)
# akstdlibConfigVersion.cmake. Nothing else should spell a version number.
#
# 0.2.0, and the minor bump is an ABI break on purpose. Fixing the confirmed
# defects in TODO.md 2.1 changed documented behaviour and, in five places,
# defects listed in UPGRADING.md changed documented behaviour and, in five places,
# signatures:
#
# aksl_realpath takes the destination's length; aksl_realpath_alloc is new
@@ -54,7 +54,7 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
endif()
# Warnings. The only warning in the tree when these went on was the unused
# `queue` parameter of aksl_tree_iterate, which TODO.md 2.2.8 had already
# `queue` parameter of aksl_tree_iterate, which UPGRADING.md had already
# recorded as a dead parameter -- so the cost of turning them on was one
# already-known defect, and the cost of leaving them off was every future one.
#
@@ -63,7 +63,7 @@ endif()
# requires at least one argument for the ...", which is a complaint about the
# macro's shape rather than about anything at this call site. Every FAIL_* in
# src/stdlib.c passes at least one argument regardless -- see the note in
# TODO.md 2.3 -- so the code is pedantic-clean; it is the expansion that is not.
# libakerror issue #15 -- so the code is pedantic-clean; it is the expansion that is not.
if(CMAKE_C_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
add_compile_options(-Wall -Wextra)
# CI turns this on. Locally it is off, because a warning that stops the build
@@ -173,7 +173,7 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
# configure at all. Rename the dependency's on the way past rather than
# dropping it: its coverage script drives its own instrumented build tree, so
# `cmake --build build-coverage --target akerror_coverage` still does the right
# thing. Remove this once the dependency namespaces it