lib/strings+test: 0-arg trim strips ASCII whitespace per Hare

The 0-arg ltrim/rtrim/trim used to return input unchanged. Hare's
0-arg form strips [' ', '\n', '\t', '\r'] (ref/hare/strings/trim.ha:6).
Aligned by delegating to bytes.ltrim/bytes.rtrim with the whitespace
set spread inline at the call site — the obvious `let ws = whitespace[0:4]`
shape produces a slice whose ptr does NOT alias storage (#40).
N-arg forms (strip-specific-runes) untouched.

Test rows retargeted to Hare's canonical inputs from trim.ha:78/85
so '\r' is exercised alongside ' '/'\t'/'\n'.
This commit is contained in:
2026-05-19 22:52:23 +09:00
parent f827429215
commit 18fe1a7a31
5 changed files with 105 additions and 54 deletions

View File

@@ -446,9 +446,8 @@ fn streq(a: str, b: str) bool = {
};
// ---- ltrim / rtrim / trim ---------------------------------------------
// ref/hare/strings/trim.ha:75-97. Bytes.ltrim whitespace-default rows
// (`ltrim(" hi") == "hi"`, etc.) deferred — they need lib/bytes
// variadic graduation.
// ref/hare/strings/trim.ha:75-97. 0-arg rows (#9) pin the ASCII
// whitespace set (' ', '\t', '\n', '\r' — ref/hare/strings/trim.ha:6).
@test fn ltrim_cases() void = {
let runes: [9]rune;
@@ -462,10 +461,12 @@ fn streq(a: str, b: str) bool = {
runes[7] = 'c';
runes[8] = 'd';
let inputs: [8]str;
let argo: [8]i32;
let argn: [8]i32;
let want: [8]str;
// 0-arg rows (8..10) strip ASCII whitespace per Hare (#9):
// only the leading side is stripped for ltrim.
let inputs: [11]str;
let argo: [11]i32;
let argn: [11]i32;
let want: [11]str;
inputs[0]=""; argo[0]=0; argn[0]=1; want[0]="";
inputs[1]="aaabc"; argo[1]=1; argn[1]=1; want[1]="bc";
inputs[2]="xyz"; argo[2]=1; argn[2]=1; want[2]="xyz";
@@ -474,9 +475,12 @@ fn streq(a: str, b: str) bool = {
inputs[5]="((()(())))())"; argo[5]=3; argn[5]=2; want[5]="";
inputs[6]="abacadabra"; argo[6]=5; argn[6]=4; want[6]="ra";
inputs[7]="hello"; argo[7]=0; argn[7]=0; want[7]="hello";
inputs[8]=" hello "; argo[8]=0; argn[8]=0; want[8]="hello ";
inputs[9]="\t\r\n hello"; argo[9]=0; argn[9]=0; want[9]="hello";
inputs[10]=" "; argo[10]=0; argn[10]=0; want[10]="";
let i: i32 = 0;
for (i < 8) {
for (i < 11) {
signalled = 1100 + i;
let argv: []rune;
argv.ptr = &runes[argo[i]];
@@ -510,10 +514,12 @@ fn streq(a: str, b: str) bool = {
runes[17] = 'a';
runes[18] = 'd';
let inputs: [8]str;
let argo: [8]i32;
let argn: [8]i32;
let want: [8]str;
// 0-arg rows (8..10) strip ASCII whitespace per Hare (#9):
// only the trailing side is stripped for rtrim.
let inputs: [11]str;
let argo: [11]i32;
let argn: [11]i32;
let want: [11]str;
inputs[0]=""; argo[0]=0; argn[0]=1; want[0]="";
inputs[1]="bcaaa"; argo[1]=1; argn[1]=1; want[1]="bc";
inputs[2]="xyz"; argo[2]=1; argn[2]=1; want[2]="xyz";
@@ -524,9 +530,13 @@ fn streq(a: str, b: str) bool = {
inputs[6]="Sentimentalized sensationalism sensationalized sentimentalisms";
argo[6]=7; argn[6]=12; want[6]="S";
inputs[7]="hello"; argo[7]=0; argn[7]=0; want[7]="hello";
inputs[8]=" hello "; argo[8]=0; argn[8]=0; want[8]=" hello";
inputs[9]="hello, world\r\n\r\n";
argo[9]=0; argn[9]=0; want[9]="hello, world";
inputs[10]=" "; argo[10]=0; argn[10]=0; want[10]="";
let i: i32 = 0;
for (i < 8) {
for (i < 11) {
signalled = 1200 + i;
let argv: []rune;
argv.ptr = &runes[argo[i]];
@@ -549,10 +559,12 @@ fn streq(a: str, b: str) bool = {
runes[6] = '[';
runes[7] = ']';
let inputs: [7]str;
let argo: [7]i32;
let argn: [7]i32;
let want: [7]str;
// 0-arg rows (7..9) strip ASCII whitespace per Hare (#9) from
// both ends.
let inputs: [10]str;
let argo: [10]i32;
let argn: [10]i32;
let want: [10]str;
inputs[0]=""; argo[0]=0; argn[0]=1; want[0]="";
inputs[1]="aaabcaaa"; argo[1]=1; argn[1]=1; want[1]="bc";
inputs[2]="xyz"; argo[2]=1; argn[2]=1; want[2]="xyz";
@@ -561,9 +573,12 @@ fn streq(a: str, b: str) bool = {
inputs[5]="[[][[[]]][][].[[]][]]][]]]";
argo[5]=6; argn[5]=2; want[5]=".";
inputs[6]="hello"; argo[6]=0; argn[6]=0; want[6]="hello";
inputs[7]=" hello "; argo[7]=0; argn[7]=0; want[7]="hello";
inputs[8]="\r\thello\n\r"; argo[8]=0; argn[8]=0; want[8]="hello";
inputs[9]=" "; argo[9]=0; argn[9]=0; want[9]="";
let i: i32 = 0;
for (i < 7) {
for (i < 10) {
signalled = 1300 + i;
let argv: []rune;
argv.ptr = &runes[argo[i]];