lib/strings+test: split sub byte-wise vs rune-wise per Hare

The byte-indexed silent-clamp sub from ww was Hare's bytesub wearing
the wrong name. Renamed accordingly; added the real rune-indexed sub
per ref/hare/strings/sub.ha:30-42, with utf8bytelenbounded helper
per :10. Both forms assert on start>end; bytesub also asserts
end<=len(s).

lib/getopt/getopt.ww:314 migrated to bytesub — its bi index is a
byte offset over the arg's bytes.

Tests cover ASCII parity, multi-byte UTF-8 (こんにちは / héllo) where
rune index ≠ byte index, and a row contrasting identical args to
make the distinction explicit. OOB-abort coverage deferred until
the assert_aborts harness lands (#38).

Selfhost combined.ww snapshots regenerated — they're bootstrap-stage
inputs and would otherwise compile the old byte-wise sub. Two-arg
default form omitted (#37, ww has no default parameter values).
This commit is contained in:
2026-05-19 22:25:06 +09:00
parent 65db360b91
commit 031f5f9ec8
6 changed files with 214 additions and 49 deletions

View File

@@ -311,7 +311,7 @@ export fn tryparse(out: *command, argv: []str, help: []help) (void | error) = {
} else {
// PARAM: glued value, or next argv slot.
if (bi + 1 < arg.len) {
let v: str = strings.sub(arg, bi + 1, arg.len);
let v: str = strings.bytesub(arg, bi + 1, arg.len);
appendoption(&opts, r, v);
advanced = true;
} else {