lib/regex: fold-2c — findall/result_freeall

findall (regex.ha:923-960) over the memio seeker: one fixed stream
for the whole string, per-call suffix substring, absolute io.seek(SET)
past the scanner readahead after each match. The append-then-mutate
m[0] fix-up is verbatim Hare (the appended header shares m's backing);
the zero-length-match rune advancement guard (ha:946-952) carries the
infinite-loop protection. search's |success|=2 unwrap is the D13
explicit 3-arm match (ww-core #14); nomem propagates.
result_freeall (ha:1119-1124) verbatim, frees no-op (#27).

Tests port Hare's own findall table (+test.ha:719-731, the three
fold-2a-reachable rows) through run_findall_case's checks, plus field
rows pinning adjacency, the one-result overlap pick, multibyte
zero-length advancement (utf8sz step != 1), idx != bytesize, the
tail-match break, and the empty no-match slice. 989's run gets the
conventional timeout-180 wrap: a regression of the zero-length guard
would otherwise hang the gate (no-op frees, so no quick OOM exit).
This commit is contained in:
2026-06-04 15:49:38 +09:00
parent 532b0a88ae
commit 48904e5ef3
3 changed files with 238 additions and 6 deletions

View File

@@ -42,7 +42,12 @@ main(void)
const char *src = "lib/regex/regex_test.ww";
char path[1024], cmd[2048];
snprintf(path, sizeof path, "%s/%s", cwd, src);
snprintf(cmd, sizeof cmd, "%s/ww run %s", bin, path);
/* timeout 180 per repo convention (732/775; test/run does not
* bound runtime): the fold-2c zero-length findall rows turn a
* regression of the ha:946-952 rune-advancement guard into an
* infinite loop (frees are no-ops, so OOM is the only other
* exit) — timeout converts the hang into a loud 124. */
snprintf(cmd, sizeof cmd, "timeout 180 %s/ww run %s", bin, path);
int rc = runwait(cmd);
if (rc != 0) {
fprintf(stderr, "regex_run FAIL: %s exited %d\n", src, rc);