lib/strings+test: graduate fromutf8 + bytesub to validating return
fromutf8(in: []u8) (str | utf8.invalid) and the bytesub form per ref/hare/strings/utf8.ha:22 and sub.ha:59. bytesub keeps its byte asserts (ww extension over Hare; predates #7). fromutf8 walks the utf8 decoder via utf8.next rather than the shorter `utf8.validate(in)?` form. Two compiler bugs in the way: cross-shape `(void | invalid) → (str | invalid)` propagation is #19, and (void | !void) match-bind locals diverge between stages / str→union lift SIGSEGVs in cstage — both filed as #48. The decoder-walk form bypasses both and matches what ref/hare/strings/utf8.ha actually does in source. getopt.ww:314 caller updated to match the new (str | invalid) return; bi+1 cannot hit a continuation byte in well-formed argv (bi is a just-matched ASCII flag), so abort spells the precondition. bytesub_cases rewritten as exhaustive match; new rows cover start-on-continuation and end-on-continuation invalid arms plus an end==s.len bypass. fromutf8_cases is new — Hare vector + edge bytes + multibyte parity rows.
This commit is contained in:
@@ -93,6 +93,7 @@
|
||||
|
||||
package getopt;
|
||||
|
||||
import encoding.utf8;
|
||||
import os;
|
||||
import strings;
|
||||
|
||||
@@ -311,7 +312,19 @@ 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.bytesub(arg, bi + 1, arg.len);
|
||||
// strings.bytesub now validates rune
|
||||
// boundaries (#7). `bi` is the byte
|
||||
// offset of the just-matched ASCII flag
|
||||
// char, so `bi + 1` cannot land on a
|
||||
// continuation byte in well-formed argv;
|
||||
// abort spells the well-formedness
|
||||
// precondition as Hare's `!` does.
|
||||
let v: str;
|
||||
match (strings.bytesub(arg, bi + 1, arg.len)) {
|
||||
case let s: str => v = s;
|
||||
case utf8.invalid =>
|
||||
abort("getopt: malformed argv UTF-8");
|
||||
};
|
||||
appendoption(&opts, r, v);
|
||||
advanced = true;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user