mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
misc (#1033)
* make conv::char32_to_utf8_unsafe() return the number of bytes it wrote add tests for DString fix pointer arithmetic in DString.insert_at Signed-off-by: Pierre Curto <pierre.curto@gmail.com> * add support to printf for %d and enums Signed-off-by: Pierre Curto <pierre.curto@gmail.com> --------- Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
This commit is contained in:
@@ -104,24 +104,28 @@ fn void! char16_to_utf8_unsafe(Char16 *ptr, usz *available, char** output)
|
||||
* @param c `The utf32 codepoint to convert`
|
||||
* @param [inout] output `the resulting buffer`
|
||||
**/
|
||||
fn void char32_to_utf8_unsafe(Char32 c, char** output)
|
||||
fn usz char32_to_utf8_unsafe(Char32 c, char** output)
|
||||
{
|
||||
switch (true)
|
||||
switch
|
||||
{
|
||||
case c < 0x7f:
|
||||
(*output)++[0] = (char)c;
|
||||
return 1;
|
||||
case c < 0x7ff:
|
||||
(*output)++[0] = (char)(0xC0 | c >> 6);
|
||||
(*output)++[0] = (char)(0x80 | (c & 0x3F));
|
||||
return 2;
|
||||
case c < 0xffff:
|
||||
(*output)++[0] = (char)(0xE0 | c >> 12);
|
||||
(*output)++[0] = (char)(0x80 | (c >> 6 & 0x3F));
|
||||
(*output)++[0] = (char)(0x80 | (c & 0x3F));
|
||||
return 3;
|
||||
default:
|
||||
(*output)++[0] = (char)(0xF0 | c >> 18);
|
||||
(*output)++[0] = (char)(0x80 | (c >> 12 & 0x3F));
|
||||
(*output)++[0] = (char)(0x80 | (c >> 6 & 0x3F));
|
||||
(*output)++[0] = (char)(0x80 | (c & 0x3F));
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -136,8 +136,7 @@ fn void DString.append_char32(&self, Char32 c)
|
||||
{
|
||||
char[4] buffer @noinit;
|
||||
char* p = &buffer;
|
||||
conv::char32_to_utf8_unsafe(c, &p);
|
||||
usz n = p - (char*)&buffer;
|
||||
usz n = conv::char32_to_utf8_unsafe(c, &p);
|
||||
self.reserve(n);
|
||||
StringData* data = self.data();
|
||||
data.chars[data.len:n] = buffer[:n];
|
||||
|
||||
@@ -11,15 +11,17 @@ fn usz! Formatter.adjust(&self, usz len) @local
|
||||
|
||||
fn uint128! int_from_any(any* arg, bool *is_neg) @private
|
||||
{
|
||||
switch (arg.type.kindof)
|
||||
{
|
||||
case TypeKind.POINTER:
|
||||
*is_neg = false;
|
||||
return (uint128)(uptr)*(void**)arg.ptr;
|
||||
case TypeKind.DISTINCT:
|
||||
case TypeKind.ENUM:
|
||||
return int_from_any(arg.as_inner(), is_neg);
|
||||
default:
|
||||
}
|
||||
*is_neg = false;
|
||||
if (arg.type.kindof == TypeKind.POINTER)
|
||||
{
|
||||
return (uint128)(uptr)*(void**)arg.ptr;
|
||||
}
|
||||
if (arg.type.kindof == TypeKind.DISTINCT)
|
||||
{
|
||||
return int_from_any(arg.as_inner(), is_neg);
|
||||
}
|
||||
switch (arg)
|
||||
{
|
||||
case bool:
|
||||
|
||||
@@ -1,4 +1,128 @@
|
||||
module std::core::dstring::tests @test;
|
||||
module std::core::dstring2 @test;
|
||||
|
||||
const TEST_STRING = "hello world";
|
||||
|
||||
fn void test_append()
|
||||
{
|
||||
DString str = dstring::new(TEST_STRING);
|
||||
defer str.free();
|
||||
String s;
|
||||
|
||||
assert(str.len() == TEST_STRING.len);
|
||||
assert(str.capacity() == 16);
|
||||
|
||||
s = str.str_view();
|
||||
assert(s == TEST_STRING, "got '%s'; want '%s'", s, TEST_STRING);
|
||||
ZString zs;
|
||||
zs = str.zstr_view();
|
||||
assert(s.ptr[s.len] == 0, "got '%c'; want 0", s.ptr[s.len]);
|
||||
|
||||
str.chop(5);
|
||||
s = str.str_view();
|
||||
assert(s == TEST_STRING[:5], "got '%s'; want '%s'", s, TEST_STRING[:5]);
|
||||
|
||||
str.append(TEST_STRING[5..]);
|
||||
s = str.str_view();
|
||||
assert(s == TEST_STRING, "got '%s'; want '%s'", s, TEST_STRING);
|
||||
|
||||
str.append_char('x');
|
||||
s = str.str_view();
|
||||
assert(s[^1] == 'x', "got '%c'; want 'x'", s[^1]);
|
||||
|
||||
str.append('y');
|
||||
s = str.str_view();
|
||||
assert(s[^1] == 'y', "got '%c'; want 'y'", s[^1]);
|
||||
|
||||
str.set(0, 'z');
|
||||
s = str.str_view();
|
||||
assert(s[0] == 'z', "got '%c'; want 'z'", s[0]);
|
||||
|
||||
str.clear();
|
||||
assert(str.len() == 0);
|
||||
|
||||
str.append_char32('é');
|
||||
s = str.str_view();
|
||||
assert(s == "é", "got '%s'; want 'é'", s);
|
||||
|
||||
str.append_utf32({ 'è', 'à' });
|
||||
s = str.str_view();
|
||||
assert(s == "éèà", "got '%s'; want 'éèà'", s);
|
||||
str.clear();
|
||||
|
||||
str.append_chars("foo");
|
||||
s = str.str_view();
|
||||
assert(s == "foo", "got '%s'; want 'foo'", s);
|
||||
str.clear();
|
||||
|
||||
str.append_repeat('x', 3);
|
||||
s = str.str_view();
|
||||
assert(s == "xxx", "got '%s'; want 'xxx'", s);
|
||||
|
||||
DString str2 = dstring::new("yyy");
|
||||
defer str2.free();
|
||||
DString str3 = str.new_concat(str2);
|
||||
defer str3.free();
|
||||
s = str3.str_view();
|
||||
assert(s == "xxxyyy", "got '%s'; want 'xxxyyy'", s);
|
||||
|
||||
str3.clear();
|
||||
str3.append_string(str2);
|
||||
s = str3.str_view();
|
||||
assert(s == "yyy", "got '%s'; want 'yyy'", s);
|
||||
}
|
||||
|
||||
fn void test_print()
|
||||
{
|
||||
DString str = dstring::new("");
|
||||
defer str.free();
|
||||
String s;
|
||||
|
||||
str.printf("_%s_", "foo");
|
||||
s = str.str_view();
|
||||
assert(s == "_foo_", "got '%s'; want '_foo_'", s);
|
||||
|
||||
str.clear();
|
||||
str.printfn("_%s_", "foo");
|
||||
s = str.str_view();
|
||||
assert(s == "_foo_\n", "got '%s'; want '_foo_\n'", s);
|
||||
}
|
||||
|
||||
fn void test_copy()
|
||||
{
|
||||
DString str = dstring::new(TEST_STRING);
|
||||
defer str.free();
|
||||
String s;
|
||||
|
||||
DString str2 = str.copy();
|
||||
defer str2.free();
|
||||
s = str2.str_view();
|
||||
assert(s == TEST_STRING, "got '%s'; want '%s'", s, TEST_STRING);
|
||||
}
|
||||
|
||||
fn void test_cmp()
|
||||
{
|
||||
DString str = dstring::new(TEST_STRING);
|
||||
defer str.free();
|
||||
|
||||
DString str2 = dstring::new(TEST_STRING);
|
||||
defer str2.free();
|
||||
|
||||
assert(str.equals(str2));
|
||||
|
||||
str2.clear();
|
||||
str2.append("hello you..");
|
||||
assert(str.len() == str2.len());
|
||||
assert(!str.less(str2));
|
||||
}
|
||||
|
||||
fn void test_join()
|
||||
{
|
||||
DString str = dstring::new_join({"hello", "world"}, " ");
|
||||
defer str.free();
|
||||
|
||||
String s = str.str_view();
|
||||
assert(s == TEST_STRING, "got '%s'; want '%s'", s, TEST_STRING);
|
||||
}
|
||||
|
||||
fn void test_insert_at()
|
||||
{
|
||||
|
||||
@@ -50,4 +50,25 @@ fn void printf_a()
|
||||
String ss = "hello world";
|
||||
s = string::printf("%.4s %.5s", ss, ss);
|
||||
assert(s == "hell hello", "got '%s'; want 'hell hello'", s);
|
||||
}
|
||||
|
||||
enum PrintfTest : ushort
|
||||
{
|
||||
ENUMA,
|
||||
ENUMB,
|
||||
}
|
||||
|
||||
fn void printf_enum()
|
||||
{
|
||||
String s;
|
||||
|
||||
s = string::printf("%s", PrintfTest.ENUMA);
|
||||
assert(s == "ENUMA", "got '%s'; want 'ENUMA'", s);
|
||||
s = string::printf("%s", PrintfTest.ENUMB);
|
||||
assert(s == "ENUMB", "got '%s'; want 'ENUMB'", s);
|
||||
|
||||
s = string::printf("%d", PrintfTest.ENUMA);
|
||||
assert(s == "0", "got '%s'; want '0'", s);
|
||||
s = string::printf("%d", PrintfTest.ENUMB);
|
||||
assert(s == "1", "got '%s'; want '1'", s);
|
||||
}
|
||||
Reference in New Issue
Block a user