lib: add missing Hare-stdlib functions (ascii/bytes/strings/path/endian)
ascii: valid, validstr, ispunct, isprint, iscntrl, isgraph, isblank, strcasecmp. bytes: hasprefix, hassuffix, rindex, rindexbyte, contains, reverse, zero. strings: rindex, sub, trimprefix, trimsuffix, ltrimbyte, rtrimbyte, trimbyte. The byte-set trim is a single-byte subset of Hare's `trim(input, exclude: rune...)`; no variadic ABI yet. path: dirname, basename, extension, join. Owned-str returns where the result isn't a borrowed view of the input (join). endian: full Hare table — be/le get/put for u16/u32/u64 plus the network-order htonu/ntohu pair extended to 32/64. lib/CLAUDE.md rewritten to reflect the post-graduation policy (tagged-union returns, owned-str returns, plan9 names, documented deviations for non-graduating modules). Makefile picks up lib/ascii and lib/fmt as wwdump_ww / w6c_ww deps so lib-only edits regenerate the affected binaries.
This commit is contained in:
@@ -21,6 +21,17 @@ export fn indexbyte(s: []u8, c: u8) (i32 | void) = {
|
||||
return;
|
||||
};
|
||||
|
||||
// rindexbyte — last index of byte `c` in `s`. Mirrors Hare's
|
||||
// bytes::rindex for the byte case.
|
||||
export fn rindexbyte(s: []u8, c: u8) (i32 | void) = {
|
||||
let i: i32 = s.len - 1;
|
||||
for (i >= 0) {
|
||||
if (s[i] == c) { return i; };
|
||||
i -= 1;
|
||||
};
|
||||
return;
|
||||
};
|
||||
|
||||
// index — first index of `sub` in `s`. Mirrors Hare's bytes::index
|
||||
// (the []u8 needle variant; the u8 needle stays as indexbyte until we
|
||||
// have union-arg dispatch). Empty `sub` matches at 0.
|
||||
@@ -41,3 +52,78 @@ export fn index(s: []u8, sub: []u8) (i32 | void) = {
|
||||
};
|
||||
return;
|
||||
};
|
||||
|
||||
// rindex — last index of `sub` in `s`. Mirrors Hare's bytes::rindex
|
||||
// for the slice case.
|
||||
export fn rindex(s: []u8, sub: []u8) (i32 | void) = {
|
||||
if (sub.len == 0) { return s.len; };
|
||||
if (sub.len > s.len) { return; };
|
||||
let i: i32 = s.len - sub.len;
|
||||
for (i >= 0) {
|
||||
let j: i32 = 0;
|
||||
let ok: bool = true;
|
||||
for (j < sub.len) {
|
||||
if (s[i + j] != sub[j]) { ok = false; j = sub.len; }
|
||||
else { j += 1; };
|
||||
};
|
||||
if (ok) { return i; };
|
||||
i -= 1;
|
||||
};
|
||||
return;
|
||||
};
|
||||
|
||||
// contains — true iff `sub` appears in `s`. Mirrors Hare's
|
||||
// bytes::contains for the slice case.
|
||||
export fn contains(s: []u8, sub: []u8) bool = {
|
||||
let r: (i32 | void) = index(s, sub);
|
||||
match (r) {
|
||||
case let i: i32 => return true;
|
||||
case void => return false;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
// hasprefix — `s` starts with `pre`. Mirrors Hare's bytes::hasprefix.
|
||||
export fn hasprefix(s: []u8, pre: []u8) bool = {
|
||||
if (pre.len > s.len) { return false; };
|
||||
let i: i32 = 0;
|
||||
for (i < pre.len) {
|
||||
if (s[i] != pre[i]) { return false; };
|
||||
i += 1;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
// hassuffix — `s` ends with `suf`. Mirrors Hare's bytes::hassuffix.
|
||||
export fn hassuffix(s: []u8, suf: []u8) bool = {
|
||||
if (suf.len > s.len) { return false; };
|
||||
let off: i32 = s.len - suf.len;
|
||||
let i: i32 = 0;
|
||||
for (i < suf.len) {
|
||||
if (s[off + i] != suf[i]) { return false; };
|
||||
i += 1;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
// reverse — in-place reverse of `s`. Mirrors Hare's bytes::reverse.
|
||||
export fn reverse(s: []u8) void = {
|
||||
let i: i32 = 0;
|
||||
let j: i32 = s.len - 1;
|
||||
for (i < j) {
|
||||
let t: u8 = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = t;
|
||||
i += 1;
|
||||
j -= 1;
|
||||
};
|
||||
};
|
||||
|
||||
// zero — set every byte of `s` to 0. Mirrors Hare's bytes::zero.
|
||||
export fn zero(s: []u8) void = {
|
||||
let i: i32 = 0;
|
||||
for (i < s.len) {
|
||||
s[i] = 0u8;
|
||||
i += 1;
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user