hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit f7c1175c1bf2188603c5d9b99ef2b5ac6059c04f
parent da96d4948ba6261ffbdd7d923ceb53b2b08f7eac
Author: Sebastian <sebastian@sebsite.pw>
Date:   Wed, 31 May 2023 01:06:20 -0400

ascii: allocate new string in strupper+strlower

Since the current plan is to make strings immutable in the const
overhaul

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mascii/string.ha | 71+++++++++++++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 47 insertions(+), 24 deletions(-)

diff --git a/ascii/string.ha b/ascii/string.ha @@ -1,30 +1,37 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> // (c) 2021 Ember Sawady <ecs@d2evs.net> +use encoding::utf8; use strings; -// Convert all ascii uppercase characters in a string to their lowercase -// representation. Modifies the original string. +// Convert all ASCII uppercase characters in a string to their lowercase +// representation, returning a new string. The return value must be freed by the +// caller. export fn strlower(s: str) str = { - let bs = strings::toutf8(s); - for (let i = 0z; i < len(bs); i += 1) { - if (bs[i] < 128 && cclass[bs[i]] & U != 0) { - bs[i] += 'a': u8 - 'A'; - }; + let new: []u8 = alloc([], len(s)); + let it = strings::iter(s); + for (true) match (strings::next(&it)) { + case let r: rune => + static append(new, utf8::encoderune(tolower(r))...); + case void => + break; }; - return s; + return strings::fromutf8(new)!; }; -// Convert all ascii lowercase characters in a string to their uppercase -// representation. Modifies the original string. +// Convert all ASCII lowercase characters in a string to their uppercase +// representation, returning a new string. The return value must be freed by the +// caller. export fn strupper(s: str) str = { - let bs = strings::toutf8(s); - for (let i = 0z; i < len(bs); i += 1) { - if (bs[i] < 128 && cclass[bs[i]] & L != 0) { - bs[i] -= 'a': u8 - 'A'; - }; + let new: []u8 = alloc([], len(s)); + let it = strings::iter(s); + for (true) match (strings::next(&it)) { + case let r: rune => + static append(new, utf8::encoderune(toupper(r))...); + case void => + break; }; - return s; + return strings::fromutf8(new)!; }; // Compares two strings by their sort order, treating all ascii capital letters @@ -46,14 +53,30 @@ export fn strcasecmp(a: str, b: str) int = { }; @test fn strcasecmp() void = { - assert(strupper("ABC") == "ABC"); - assert(strlower("ABC") == "abc"); - assert(strupper("abc") == "ABC"); - assert(strlower("abc") == "abc"); - assert(strupper("[[[") == "[[["); - assert(strlower("[[[") == "[[["); - assert(strupper("こ") == "こ"); - assert(strlower("こ") == "こ"); + let s = strupper("ABC"); + assert(s == "ABC"); + free(s); + s = strlower("ABC"); + assert(s == "abc"); + free(s); + s = strupper("abc"); + assert(s == "ABC"); + free(s); + s = strlower("abc"); + assert(s == "abc"); + free(s); + s = strupper("[[["); + assert(s == "[[["); + free(s); + s = strlower("[[["); + assert(s == "[[["); + free(s); + s = strupper("こ"); + assert(s == "こ"); + free(s); + s = strlower("こ"); + assert(s == "こ"); + free(s); assert(strcasecmp("ABC", "ABC") == 0); assert(strcasecmp("ABC", "abc") == 0);