From e35984b6c67f2adf1c12d84c48fdf4f01be020e5 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 11 May 2011 00:05:03 -0400 Subject: [PATCH] Introduce str_slice runtime function This reduces the time to execute the new lib-str tests from 1:40ish to a few seconds and will eventually allow the full lib-sha1 test to run in a reasonable amount of time. XFAIL lib-str in stage0 - it will run very slowly until the next snapshot. --- src/lib/Str.rs | 12 +++++------- src/rt/rust_builtin.cpp | 18 ++++++++++++++++++ src/rt/rustrt.def.in | 1 + src/test/run-pass/lib-str.rs | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/lib/Str.rs b/src/lib/Str.rs index ba0d45de529..6e39b3599f4 100644 --- a/src/lib/Str.rs +++ b/src/lib/Str.rs @@ -12,6 +12,7 @@ fn str_from_cstr(sbuf cstr) -> str; fn str_from_buf(sbuf buf, uint len) -> str; fn str_push_byte(str s, uint byte) -> str; + fn str_slice(str s, uint begin, uint end) -> str; fn refcount[T](str s) -> uint; } @@ -384,13 +385,10 @@ fn substr(str s, uint begin, uint len) -> str { } fn slice(str s, uint begin, uint end) -> str { - let str accum = ""; - let uint i = begin; - while (i < end) { - push_byte(accum, s.(i)); - i += 1u; - } - ret accum; + // FIXME: Typestate precondition + assert (begin <= end); + assert (end <= Str.byte_len(s)); + ret rustrt.str_slice(s, begin, end); } fn shift_byte(&mutable str s) -> u8 { diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 297b9df7d95..bc2c5adde60 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -226,6 +226,24 @@ str_push_byte(rust_task* task, rust_str* v, size_t byte) return v; } +extern "C" CDECL rust_str* +str_slice(rust_task* task, rust_str* v, size_t begin, size_t end) +{ + size_t len = end - begin; + rust_str *st = + vec_alloc_with_data(task, + len + 1, // +1 to fit at least '\0' + len, + 1, + len ? v->data + begin : NULL); + if (!st) { + task->fail(2); + return NULL; + } + st->data[st->fill++] = '\0'; + return st; +} + extern "C" CDECL char const * str_buf(rust_task *task, rust_str *s) { diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index b2d424632d1..1258f97b9ae 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -32,6 +32,7 @@ str_from_buf str_from_cstr str_from_vec str_push_byte +str_slice str_vec task_sleep unsafe_vec_to_mut diff --git a/src/test/run-pass/lib-str.rs b/src/test/run-pass/lib-str.rs index 58779f674e3..8985c22e51f 100644 --- a/src/test/run-pass/lib-str.rs +++ b/src/test/run-pass/lib-str.rs @@ -1,3 +1,6 @@ +// xfail-boot +// xfail-stage0 + use std; import std.Str; @@ -98,6 +101,36 @@ fn test_to_upper() { assert (Str.eq(expected, actual)); } +fn test_slice() { + assert (Str.eq("ab", Str.slice("abc", 0u, 2u))); + assert (Str.eq("bc", Str.slice("abc", 1u, 3u))); + assert (Str.eq("", Str.slice("abc", 1u, 1u))); + + fn a_million_letter_a() -> str { + auto i = 0; + auto res = ""; + while (i < 100000) { + res += "aaaaaaaaaa"; + i += 1; + } + ret res; + } + + fn half_a_million_letter_a() -> str { + auto i = 0; + auto res = ""; + while (i < 100000) { + res += "aaaaa"; + i += 1; + } + ret res; + } + + assert (Str.eq(half_a_million_letter_a(), + Str.slice(a_million_letter_a(), + 0u, + 500000u))); +} fn main() { test_bytes_len(); @@ -108,4 +141,5 @@ fn main() { test_concat(); test_connect(); test_to_upper(); + test_slice(); } -- GitLab