contains(s, needle: (u8|[]u8)) -> contains(s: []u8, needles:
(u8|[]u8)...) bool per ref/hare/bytes/contains.ha:6.
Body: for-loop over needles.len; inner match (needles[i]) with u8/
[]u8 arms each forwarding to index(s, ...) with early return true
on the i32-match arm. 0-arg returns false per Hare spec. Mirrors
sister #9 strings.contains body shape modulo element type.
Sister of #9 (7c5463c). Element shape (u8|[]u8) — slice payload +
scalar u8 — structurally distinct from (str|rune). Was flagged as
potential new-latent surface; verified clean by 967_bytes_run +
cross-module 750_mklabel_modscoped[bytes_strings_contains] +
995_self_rebuild byte-id. No cgen wedge fired — #15 frame growth +
#12 sum-tag forward + #16 fnparamslookupmod close it on the slice-
payload variant too.
contains_cases adds 5 variadic rows (signalled 1700+i): 0-arg false,
1-arg slice hit, 1-arg u8 hit, 3-arg mixed middle-hit, 3-arg all-miss.
Module-header non-variadic divergence note removed.
make test 126/126; ww2==ww3==ww4 byte-id holds via 995_self_rebuild.
260 lines
8.5 KiB
Plaintext
260 lines
8.5 KiB
Plaintext
// bytestest — exercises lib/bytes. Run with
|
|
// `out/bin/ww run lib/bytes/bytestest.ww`. Same signalled-then-
|
|
// fail()-with-+10 pattern as hex / utf8 / time tests: non-zero exit
|
|
// pinpoints the failing scenario.
|
|
//
|
|
// Vectors mirror Hare's @test fns in ref/hare/bytes/equal.ha,
|
|
// ref/hare/bytes/index.ha, ref/hare/bytes/contains.ha.
|
|
|
|
package bytes;
|
|
|
|
import bytes;
|
|
import os;
|
|
|
|
let signalled: i32 = 0;
|
|
fn fail() void = { os.exit(signalled + 10); };
|
|
|
|
// ---- equal ------------------------------------------------------------
|
|
// ref/hare/bytes/equal.ha:21.
|
|
|
|
@test fn equal_cases() void = {
|
|
let a: [3]u8; a[0] = 1u8; a[1] = 2u8; a[2] = 3u8;
|
|
let b: [3]u8; b[0] = 1u8; b[1] = 2u8; b[2] = 3u8;
|
|
let c: [3]u8; c[0] = 1u8; c[1] = 4u8; c[2] = 5u8;
|
|
let d: [4]u8; d[0] = 1u8; d[1] = 2u8; d[2] = 3u8; d[3] = 4u8;
|
|
let e: [2]u8; e[0] = 1u8; e[1] = 2u8;
|
|
let z: [1]u8;
|
|
if (!bytes.equal(a[0:3], b[0:3])) { fail(); };
|
|
if ( bytes.equal(a[0:3], c[0:3])) { fail(); };
|
|
if ( bytes.equal(a[0:3], d[0:4])) { fail(); };
|
|
if ( bytes.equal(a[0:3], e[0:2])) { fail(); };
|
|
if (!bytes.equal(z[0:0], z[0:0])) { fail(); }; // empty-empty
|
|
};
|
|
|
|
// ---- index(u8) --------------------------------------------------------
|
|
// ref/hare/bytes/index.ha:112.
|
|
|
|
@test fn index_byte_cases() void = {
|
|
let a: [4]u8; a[0] = 1u8; a[1] = 3u8; a[2] = 3u8; a[3] = 7u8;
|
|
match (bytes.index(a[0:4], 1u8)) {
|
|
case let i: i32 => { if (i != 0) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
match (bytes.index(a[0:4], 3u8)) {
|
|
case let i: i32 => { if (i != 1) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
match (bytes.index(a[0:4], 7u8)) {
|
|
case let i: i32 => { if (i != 3) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
match (bytes.index(a[0:4], 42u8)) {
|
|
case let i: i32 => { fail(); };
|
|
case void => void;
|
|
};
|
|
let z: [1]u8;
|
|
match (bytes.index(z[0:0], 42u8)) {
|
|
case let i: i32 => { fail(); };
|
|
case void => void;
|
|
};
|
|
};
|
|
|
|
// ---- index([]u8) ------------------------------------------------------
|
|
// ref/hare/bytes/index.ha:128-139. Vector strings copied verbatim where
|
|
// representable as ASCII byte sequences.
|
|
|
|
@test fn index_slice_cases() void = {
|
|
let h1: [4]u8; h1[0] = 1u8; h1[1] = 42u8; h1[2] = 24u8; h1[3] = 0u8;
|
|
let n1: [2]u8; n1[0] = 42u8; n1[1] = 24u8;
|
|
match (bytes.index(h1[0:3], n1[0:2])) {
|
|
case let i: i32 => { if (i != 1) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
|
|
let h2: [4]u8; h2[0] = 1u8; h2[1] = 3u8; h2[2] = 3u8; h2[3] = 7u8;
|
|
let n2: [2]u8; n2[0] = 3u8; n2[1] = 3u8;
|
|
match (bytes.index(h2[0:4], n2[0:2])) {
|
|
case let i: i32 => { if (i != 1) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
|
|
// needle longer than haystack — void
|
|
let h3: [3]u8; h3[0] = 1u8; h3[1] = 2u8; h3[2] = 3u8;
|
|
let n3: [4]u8; n3[0] = 1u8; n3[1] = 2u8; n3[2] = 3u8; n3[3] = 4u8;
|
|
match (bytes.index(h3[0:3], n3[0:4])) {
|
|
case let i: i32 => { fail(); };
|
|
case void => void;
|
|
};
|
|
|
|
// len(haystack) == len(needle), match — offset 0
|
|
let h4: [2]u8; h4[0] = 42u8; h4[1] = 20u8;
|
|
let n4: [2]u8; n4[0] = 42u8; n4[1] = 20u8;
|
|
match (bytes.index(h4[0:2], n4[0:2])) {
|
|
case let i: i32 => { if (i != 0) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
|
|
// len(haystack) == len(needle), no match — void
|
|
let h5: [4]u8; h5[0] = 1u8; h5[1] = 1u8; h5[2] = 1u8; h5[3] = 2u8;
|
|
let n5: [4]u8; n5[0] = 1u8; n5[1] = 1u8; n5[2] = 1u8; n5[3] = 3u8;
|
|
match (bytes.index(h5[0:4], n5[0:4])) {
|
|
case let i: i32 => { fail(); };
|
|
case void => void;
|
|
};
|
|
|
|
// Partial-prefix recovery — needle [1,1,2] aligns at i=1 after the
|
|
// false-start at i=0 ([1,1,1] mismatches at byte 2). Pins the
|
|
// naive scanner's restart discipline.
|
|
let h6: [4]u8; h6[0] = 1u8; h6[1] = 1u8; h6[2] = 1u8; h6[3] = 2u8;
|
|
let n6s: [3]u8; n6s[0] = 1u8; n6s[1] = 1u8; n6s[2] = 2u8;
|
|
match (bytes.index(h6[0:4], n6s[0:3])) {
|
|
case let i: i32 => { if (i != 1) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
|
|
// Same shape, longer haystack with no match anywhere.
|
|
let h7: [5]u8; h7[0] = 1u8; h7[1] = 1u8; h7[2] = 1u8; h7[3] = 3u8; h7[4] = 2u8;
|
|
let n7: [4]u8; n7[0] = 1u8; n7[1] = 1u8; n7[2] = 1u8; n7[3] = 2u8;
|
|
match (bytes.index(h7[0:5], n7[0:4])) {
|
|
case let i: i32 => { fail(); };
|
|
case void => void;
|
|
};
|
|
|
|
// empty needle — Hare returns 0 (ref/hare/bytes/index.ha:63).
|
|
let z: [1]u8;
|
|
let zn: [1]u8;
|
|
match (bytes.index(h2[0:4], zn[0:0])) {
|
|
case let i: i32 => { if (i != 0) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
// empty haystack, non-empty needle — void
|
|
match (bytes.index(z[0:0], n3[0:3])) {
|
|
case let i: i32 => { fail(); };
|
|
case void => void;
|
|
};
|
|
|
|
// single-byte slice needle — should semantically equal u8 arm
|
|
let n6: [1]u8; n6[0] = 7u8;
|
|
match (bytes.index(h2[0:4], n6[0:1])) {
|
|
case let i: i32 => { if (i != 3) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
};
|
|
|
|
// ---- rindex(u8) -------------------------------------------------------
|
|
// ref/hare/bytes/index.ha:118.
|
|
|
|
@test fn rindex_byte_cases() void = {
|
|
let a: [4]u8; a[0] = 1u8; a[1] = 3u8; a[2] = 3u8; a[3] = 7u8;
|
|
match (bytes.rindex(a[0:4], 3u8)) {
|
|
case let i: i32 => { if (i != 2) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
match (bytes.rindex(a[0:4], 42u8)) {
|
|
case let i: i32 => { fail(); };
|
|
case void => void;
|
|
};
|
|
let z: [1]u8;
|
|
match (bytes.rindex(z[0:0], 42u8)) {
|
|
case let i: i32 => { fail(); };
|
|
case void => void;
|
|
};
|
|
};
|
|
|
|
// ---- rindex([]u8) -----------------------------------------------------
|
|
// ref/hare/bytes/index.ha:123-125. Distinguishes from index when the
|
|
// needle appears more than once.
|
|
|
|
@test fn rindex_slice_cases() void = {
|
|
let a: [4]u8; a[0] = 1u8; a[1] = 1u8; a[2] = 1u8; a[3] = 2u8;
|
|
let n11: [2]u8; n11[0] = 1u8; n11[1] = 1u8;
|
|
match (bytes.rindex(a[0:4], n11[0:2])) {
|
|
case let i: i32 => { if (i != 1) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
let n12: [2]u8; n12[0] = 1u8; n12[1] = 2u8;
|
|
match (bytes.rindex(a[0:4], n12[0:2])) {
|
|
case let i: i32 => { if (i != 2) { fail(); }; };
|
|
case void => { fail(); };
|
|
};
|
|
// absent
|
|
let n99: [2]u8; n99[0] = 9u8; n99[1] = 9u8;
|
|
match (bytes.rindex(a[0:4], n99[0:2])) {
|
|
case let i: i32 => { fail(); };
|
|
case void => void;
|
|
};
|
|
};
|
|
|
|
// ---- contains ---------------------------------------------------------
|
|
|
|
@test fn contains_cases() void = {
|
|
let a: [4]u8; a[0] = 1u8; a[1] = 3u8; a[2] = 3u8; a[3] = 7u8;
|
|
if (!bytes.contains(a[0:4], 7u8)) { fail(); };
|
|
if ( bytes.contains(a[0:4], 42u8)) { fail(); };
|
|
let n: [2]u8; n[0] = 3u8; n[1] = 3u8;
|
|
if (!bytes.contains(a[0:4], n[0:2])) { fail(); };
|
|
let m: [2]u8; m[0] = 9u8; m[1] = 9u8;
|
|
if ( bytes.contains(a[0:4], m[0:2])) { fail(); };
|
|
|
|
// Variadic rows. ref/hare/bytes/contains.ha:6.
|
|
signalled = 1700;
|
|
if ( bytes.contains(a[0:4])) { fail(); };
|
|
signalled = 1701;
|
|
if (!bytes.contains(a[0:4], n[0:2])) { fail(); };
|
|
signalled = 1702;
|
|
if (!bytes.contains(a[0:4], 7u8)) { fail(); };
|
|
signalled = 1703;
|
|
if (!bytes.contains(a[0:4], m[0:2], n[0:2], 42u8)) { fail(); };
|
|
signalled = 1704;
|
|
if ( bytes.contains(a[0:4], m[0:2], 42u8, m[0:2])) { fail(); };
|
|
};
|
|
|
|
// ---- hasprefix --------------------------------------------------------
|
|
// ref/hare/bytes/contains.ha:25.
|
|
|
|
@test fn hasprefix_cases() void = {
|
|
let z: [1]u8;
|
|
if (!bytes.hasprefix(z[0:0], z[0:0])) { fail(); };
|
|
let one: [1]u8; one[0] = 0u8;
|
|
if (!bytes.hasprefix(one[0:1], z[0:0])) { fail(); };
|
|
if ( bytes.hasprefix(z[0:0], one[0:1])) { fail(); };
|
|
let a: [3]u8; a[0] = 1u8; a[1] = 2u8; a[2] = 3u8;
|
|
let p12: [2]u8; p12[0] = 1u8; p12[1] = 2u8;
|
|
if (!bytes.hasprefix(a[0:3], p12[0:2])) { fail(); };
|
|
let p11: [2]u8; p11[0] = 1u8; p11[1] = 1u8;
|
|
if ( bytes.hasprefix(a[0:3], p11[0:2])) { fail(); };
|
|
let pl: [4]u8; pl[0] = 1u8; pl[1] = 2u8; pl[2] = 3u8; pl[3] = 4u8;
|
|
if ( bytes.hasprefix(a[0:3], pl[0:4])) { fail(); };
|
|
};
|
|
|
|
// ---- hassuffix --------------------------------------------------------
|
|
// ref/hare/bytes/contains.ha:40.
|
|
|
|
@test fn hassuffix_cases() void = {
|
|
let z: [1]u8;
|
|
if (!bytes.hassuffix(z[0:0], z[0:0])) { fail(); };
|
|
let one: [1]u8; one[0] = 0u8;
|
|
if (!bytes.hassuffix(one[0:1], z[0:0])) { fail(); };
|
|
if ( bytes.hassuffix(z[0:0], one[0:1])) { fail(); };
|
|
let a: [3]u8; a[0] = 1u8; a[1] = 2u8; a[2] = 3u8;
|
|
let s23: [2]u8; s23[0] = 2u8; s23[1] = 3u8;
|
|
if (!bytes.hassuffix(a[0:3], s23[0:2])) { fail(); };
|
|
let s22: [2]u8; s22[0] = 2u8; s22[1] = 2u8;
|
|
if ( bytes.hassuffix(a[0:3], s22[0:2])) { fail(); };
|
|
let a4: [4]u8; a4[0] = 1u8; a4[1] = 2u8; a4[2] = 3u8; a4[3] = 4u8;
|
|
let s234: [3]u8; s234[0] = 2u8; s234[1] = 3u8; s234[2] = 4u8;
|
|
if (!bytes.hassuffix(a4[0:4], s234[0:3])) { fail(); };
|
|
};
|
|
|
|
export fn main() i32 = {
|
|
signalled = 1; equal_cases();
|
|
signalled = 2; index_byte_cases();
|
|
signalled = 3; index_slice_cases();
|
|
signalled = 4; rindex_byte_cases();
|
|
signalled = 5; rindex_slice_cases();
|
|
signalled = 6; contains_cases();
|
|
signalled = 7; hasprefix_cases();
|
|
signalled = 8; hassuffix_cases();
|
|
return 0;
|
|
};
|