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:
M | ascii/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);