aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Anderson <[email protected]>2011-05-11 00:05:03 -0400
committerBrian Anderson <[email protected]>2011-05-11 01:38:16 -0400
commite35984b6c67f2adf1c12d84c48fdf4f01be020e5 (patch)
tree73ee96cb57bcb696357ccc9252b2dd499905131e
parentMore alias-ification of trans. (diff)
downloadrust-e35984b6c67f2adf1c12d84c48fdf4f01be020e5.tar.xz
rust-e35984b6c67f2adf1c12d84c48fdf4f01be020e5.zip
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.
-rw-r--r--src/lib/Str.rs12
-rw-r--r--src/rt/rust_builtin.cpp18
-rw-r--r--src/rt/rustrt.def.in1
-rw-r--r--src/test/run-pass/lib-str.rs34
4 files changed, 58 insertions, 7 deletions
diff --git a/src/lib/Str.rs b/src/lib/Str.rs
index ba0d45de..6e39b359 100644
--- a/src/lib/Str.rs
+++ b/src/lib/Str.rs
@@ -12,6 +12,7 @@ native "rust" mod rustrt {
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 297b9df7..bc2c5add 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 b2d42463..1258f97b 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 58779f67..8985c22e 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();
}