core: Convert declarations to not use the trailing 'unsafe' notation
This commit is contained in:
parent
3ba7ca5c9f
commit
fad307d7b4
19 changed files with 577 additions and 463 deletions
|
@ -2,9 +2,9 @@
|
|||
|
||||
export ptr_eq;
|
||||
|
||||
pure fn ptr_eq<T>(a: @T, b: @T) -> bool unchecked {
|
||||
pure fn ptr_eq<T>(a: @T, b: @T) -> bool {
|
||||
#[doc = "Determine if two shared boxes point to the same object"];
|
||||
ptr::addr_of(*a) == ptr::addr_of(*b)
|
||||
unsafe { ptr::addr_of(*a) == ptr::addr_of(*b) }
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -231,7 +231,7 @@ fn test_to_digit() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_ascii() unsafe {
|
||||
fn test_is_ascii() {
|
||||
assert str::all("banana", char::is_ascii);
|
||||
assert ! str::all("ประเทศไทย中华Việt Nam", char::is_ascii);
|
||||
}
|
||||
|
|
|
@ -210,13 +210,13 @@ fn recv_<T: send>(p: *rust_port) -> T {
|
|||
ret res;
|
||||
}
|
||||
|
||||
fn peek_(p: *rust_port) -> bool unsafe {
|
||||
fn peek_(p: *rust_port) -> bool {
|
||||
rustrt::rust_port_size(p) != 0u as libc::size_t
|
||||
}
|
||||
|
||||
#[doc = "Receive on one of two ports"]
|
||||
fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
|
||||
-> either<A, B> unsafe {
|
||||
-> either<A, B> {
|
||||
let ports = [(**p_a).po, (**p_b).po];
|
||||
let n_ports = 2 as libc::size_t;
|
||||
let yield = 0u, yieldp = ptr::addr_of(yield);
|
||||
|
|
|
@ -81,7 +81,7 @@ mod ct {
|
|||
enum piece { piece_string(str), piece_conv(conv), }
|
||||
type error_fn = fn@(str) -> ! ;
|
||||
|
||||
fn parse_fmt_string(s: str, error: error_fn) -> [piece] unsafe {
|
||||
fn parse_fmt_string(s: str, error: error_fn) -> [piece] {
|
||||
let mut pieces: [piece] = [];
|
||||
let lim = str::len(s);
|
||||
let mut buf = "";
|
||||
|
@ -225,7 +225,7 @@ mod ct {
|
|||
} else { {count: count_implied, next: i} };
|
||||
}
|
||||
fn parse_type(s: str, i: uint, lim: uint, error: error_fn) ->
|
||||
{ty: ty, next: uint} unsafe {
|
||||
{ty: ty, next: uint} {
|
||||
if i >= lim { error("missing type in conversion"); }
|
||||
let tstr = str::slice(s, i, i+1u);
|
||||
// TODO: Do we really want two signed types here?
|
||||
|
@ -314,7 +314,7 @@ mod rt {
|
|||
let mut s = str::from_char(c);
|
||||
ret pad(cv, s, pad_nozero);
|
||||
}
|
||||
fn conv_str(cv: conv, s: str) -> str unsafe {
|
||||
fn conv_str(cv: conv, s: str) -> str {
|
||||
// For strings, precision is the maximum characters
|
||||
// displayed
|
||||
let mut unpadded = alt cv.precision {
|
||||
|
@ -378,7 +378,7 @@ mod rt {
|
|||
};
|
||||
}
|
||||
enum pad_mode { pad_signed, pad_unsigned, pad_nozero, pad_float }
|
||||
fn pad(cv: conv, &s: str, mode: pad_mode) -> str unsafe {
|
||||
fn pad(cv: conv, &s: str, mode: pad_mode) -> str {
|
||||
let uwidth : uint = alt cv.width {
|
||||
count_implied { ret s; }
|
||||
count_is(width) {
|
||||
|
|
|
@ -93,10 +93,10 @@ fn parse_buf(buf: [u8], radix: uint) -> option<T> {
|
|||
fn from_str(s: str) -> option<T> { parse_buf(str::bytes(s), 10u) }
|
||||
|
||||
#[doc = "Convert to a string in a given base"]
|
||||
fn to_str(n: T, radix: uint) -> str unsafe {
|
||||
fn to_str(n: T, radix: uint) -> str {
|
||||
to_str_bytes(n, radix) {|slice|
|
||||
vec::unpack_slice(slice) {|p, len|
|
||||
str::unsafe::from_buf_len(p, len)
|
||||
unsafe { str::unsafe::from_buf_len(p, len) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,13 +192,13 @@ fn convert_whence(whence: seek_style) -> i32 {
|
|||
}
|
||||
|
||||
impl of reader for *libc::FILE {
|
||||
fn read_bytes(len: uint) -> [u8] unsafe {
|
||||
fn read_bytes(len: uint) -> [u8] {
|
||||
let mut buf : [mut u8] = [mut];
|
||||
vec::reserve(buf, len);
|
||||
vec::as_mut_buf(buf) {|b|
|
||||
let read = libc::fread(b as *mut c_void, 1u as size_t,
|
||||
len as size_t, self);
|
||||
vec::unsafe::set_len(buf, read as uint);
|
||||
unsafe { vec::unsafe::set_len(buf, read as uint) };
|
||||
}
|
||||
ret vec::from_mut(buf);
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ impl <T: writer, C> of writer for {base: T, cleanup: C} {
|
|||
}
|
||||
|
||||
impl of writer for *libc::FILE {
|
||||
fn write(v: [const u8]/&) unsafe {
|
||||
fn write(v: [const u8]/&) {
|
||||
vec::unpack_const_slice(v) {|vbuf, len|
|
||||
let nout = libc::fwrite(vbuf as *c_void, len as size_t,
|
||||
1u as size_t, self);
|
||||
|
@ -357,7 +357,7 @@ fn FILE_writer(f: *libc::FILE, cleanup: bool) -> writer {
|
|||
}
|
||||
|
||||
impl of writer for fd_t {
|
||||
fn write(v: [const u8]/&) unsafe {
|
||||
fn write(v: [const u8]/&) {
|
||||
let mut count = 0u;
|
||||
vec::unpack_const_slice(v) {|vbuf, len|
|
||||
while count < len {
|
||||
|
|
|
@ -70,7 +70,7 @@ pure fn iter<T>(opt: option<T>, f: fn(T)) {
|
|||
alt opt { none { } some(t) { f(t); } }
|
||||
}
|
||||
|
||||
pure fn unwrap<T>(-opt: option<T>) -> T unsafe {
|
||||
pure fn unwrap<T>(-opt: option<T>) -> T {
|
||||
#[doc = "
|
||||
Moves a value out of an option type and returns it.
|
||||
|
||||
|
@ -78,13 +78,15 @@ pure fn unwrap<T>(-opt: option<T>) -> T unsafe {
|
|||
option types without copying them.
|
||||
"];
|
||||
|
||||
let addr = alt opt {
|
||||
some(x) { ptr::addr_of(x) }
|
||||
none { fail "option none" }
|
||||
};
|
||||
let liberated_value = unsafe::reinterpret_cast(*addr);
|
||||
unsafe::forget(opt);
|
||||
ret liberated_value;
|
||||
unsafe {
|
||||
let addr = alt opt {
|
||||
some(x) { ptr::addr_of(x) }
|
||||
none { fail "option none" }
|
||||
};
|
||||
let liberated_value = unsafe::reinterpret_cast(*addr);
|
||||
unsafe::forget(opt);
|
||||
ret liberated_value;
|
||||
}
|
||||
}
|
||||
|
||||
impl extensions<T> for option<T> {
|
||||
|
|
|
@ -180,19 +180,21 @@ mod global_env {
|
|||
}
|
||||
}
|
||||
|
||||
fn global_env_task(msg_po: comm::port<msg>) unsafe {
|
||||
priv::weaken_task {|weak_po|
|
||||
loop {
|
||||
alt comm::select2(msg_po, weak_po) {
|
||||
either::left(msg_getenv(n, resp_ch)) {
|
||||
comm::send(resp_ch, impl::getenv(n))
|
||||
}
|
||||
either::left(msg_setenv(n, v, resp_ch)) {
|
||||
comm::send(resp_ch, impl::setenv(n, v))
|
||||
}
|
||||
either::right(_) {
|
||||
break;
|
||||
}
|
||||
fn global_env_task(msg_po: comm::port<msg>) {
|
||||
unsafe {
|
||||
priv::weaken_task {|weak_po|
|
||||
loop {
|
||||
alt comm::select2(msg_po, weak_po) {
|
||||
either::left(msg_getenv(n, resp_ch)) {
|
||||
comm::send(resp_ch, impl::getenv(n))
|
||||
}
|
||||
either::left(msg_setenv(n, v, resp_ch)) {
|
||||
comm::send(resp_ch, impl::setenv(n, v))
|
||||
}
|
||||
either::right(_) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,18 +203,20 @@ mod global_env {
|
|||
mod impl {
|
||||
|
||||
#[cfg(unix)]
|
||||
fn getenv(n: str) -> option<str> unsafe {
|
||||
let s = str::as_c_str(n, libc::getenv);
|
||||
ret if unsafe::reinterpret_cast(s) == 0 {
|
||||
option::none::<str>
|
||||
} else {
|
||||
let s = unsafe::reinterpret_cast(s);
|
||||
option::some::<str>(str::unsafe::from_buf(s))
|
||||
};
|
||||
fn getenv(n: str) -> option<str> {
|
||||
unsafe {
|
||||
let s = str::as_c_str(n, libc::getenv);
|
||||
ret if unsafe::reinterpret_cast(s) == 0 {
|
||||
option::none::<str>
|
||||
} else {
|
||||
let s = unsafe::reinterpret_cast(s);
|
||||
option::some::<str>(str::unsafe::from_buf(s))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn getenv(n: str) -> option<str> unsafe {
|
||||
fn getenv(n: str) -> option<str> {
|
||||
import libc::types::os::arch::extra::*;
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import win32::*;
|
||||
|
@ -362,21 +366,23 @@ fn dll_filename(base: str) -> str {
|
|||
fn self_exe_path() -> option<path> {
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
fn load_self() -> option<path> unsafe {
|
||||
import libc::funcs::bsd44::*;
|
||||
import libc::consts::os::extra::*;
|
||||
fill_charp_buf() {|buf, sz|
|
||||
let mib = [CTL_KERN as c_int,
|
||||
KERN_PROC as c_int,
|
||||
KERN_PROC_PATHNAME as c_int, -1 as c_int];
|
||||
sysctl(vec::unsafe::to_ptr(mib), vec::len(mib) as c_uint,
|
||||
buf as *mut c_void, ptr::mut_addr_of(sz),
|
||||
ptr::null(), 0u as size_t) == (0 as c_int)
|
||||
fn load_self() -> option<path> {
|
||||
unsafe {
|
||||
import libc::funcs::bsd44::*;
|
||||
import libc::consts::os::extra::*;
|
||||
fill_charp_buf() {|buf, sz|
|
||||
let mib = [CTL_KERN as c_int,
|
||||
KERN_PROC as c_int,
|
||||
KERN_PROC_PATHNAME as c_int, -1 as c_int];
|
||||
sysctl(vec::unsafe::to_ptr(mib), vec::len(mib) as c_uint,
|
||||
buf as *mut c_void, ptr::mut_addr_of(sz),
|
||||
ptr::null(), 0u as size_t) == (0 as c_int)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn load_self() -> option<path> unsafe {
|
||||
fn load_self() -> option<path> {
|
||||
import libc::funcs::posix01::unistd::readlink;
|
||||
fill_charp_buf() {|buf, sz|
|
||||
as_c_charp("/proc/self/exe") { |proc_self_buf|
|
||||
|
@ -386,9 +392,10 @@ fn self_exe_path() -> option<path> {
|
|||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn load_self() -> option<path> unsafe {
|
||||
fn load_self() -> option<path> {
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::*;
|
||||
|
||||
fill_charp_buf() {|buf, sz|
|
||||
_NSGetExecutablePath(buf, ptr::mut_addr_of(sz as u32))
|
||||
== (0 as c_int)
|
||||
|
@ -396,7 +403,7 @@ fn self_exe_path() -> option<path> {
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn load_self() -> option<path> unsafe {
|
||||
fn load_self() -> option<path> {
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::types::os::arch::extra::*;
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
|
@ -525,14 +532,14 @@ fn make_dir(p: path, mode: c_int) -> bool {
|
|||
ret mkdir(p, mode);
|
||||
|
||||
#[cfg(windows)]
|
||||
fn mkdir(p: path, _mode: c_int) -> bool unsafe {
|
||||
fn mkdir(p: path, _mode: c_int) -> bool {
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::types::os::arch::extra::*;
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import win32::*;
|
||||
// FIXME: turn mode into something useful? #2623
|
||||
as_utf16_p(p) {|buf|
|
||||
CreateDirectoryW(buf, unsafe::reinterpret_cast(0))
|
||||
CreateDirectoryW(buf, unsafe { unsafe::reinterpret_cast(0) })
|
||||
!= (0 as BOOL)
|
||||
}
|
||||
}
|
||||
|
@ -645,7 +652,7 @@ fn copy_file(from: path, to: path) -> bool {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn do_copy_file(from: path, to: path) -> bool unsafe {
|
||||
fn do_copy_file(from: path, to: path) -> bool {
|
||||
let istream = as_c_charp(from) {|fromp|
|
||||
as_c_charp("rb") {|modebuf|
|
||||
libc::fopen(fromp, modebuf)
|
||||
|
|
|
@ -105,14 +105,20 @@ Given paths `pre` and `post, removes any trailing path separator on `pre` and
|
|||
any leading path separator on `post`, and returns the concatenation of the two
|
||||
with a single path separator between them.
|
||||
"]
|
||||
fn connect(pre: path, post: path) -> path unsafe {
|
||||
fn connect(pre: path, post: path) -> path {
|
||||
let mut pre_ = pre;
|
||||
let mut post_ = post;
|
||||
let sep = consts::path_sep as u8;
|
||||
let pre_len = str::len(pre);
|
||||
let post_len = str::len(post);
|
||||
if pre_len > 1u && pre[pre_len-1u] == sep { str::unsafe::pop_byte(pre_); }
|
||||
if post_len > 1u && post[0] == sep { str::unsafe::shift_byte(post_); }
|
||||
unsafe {
|
||||
if pre_len > 1u && pre[pre_len-1u] == sep {
|
||||
str::unsafe::pop_byte(pre_);
|
||||
}
|
||||
if post_len > 1u && post[0] == sep {
|
||||
str::unsafe::shift_byte(post_);
|
||||
}
|
||||
}
|
||||
ret pre_ + path_sep() + post_;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ unsafe fn chan_from_global_ptr<T: send>(
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_global_chan1() unsafe {
|
||||
fn test_from_global_chan1() {
|
||||
|
||||
// This is unreadable, right?
|
||||
|
||||
|
@ -91,11 +91,13 @@ fn test_from_global_chan1() unsafe {
|
|||
let globchanp = ptr::addr_of(globchan);
|
||||
|
||||
// Create the global channel, attached to a new task
|
||||
let ch = chan_from_global_ptr(globchanp, task::builder) {|po|
|
||||
let ch = comm::recv(po);
|
||||
comm::send(ch, true);
|
||||
let ch = comm::recv(po);
|
||||
comm::send(ch, true);
|
||||
let ch = unsafe {
|
||||
chan_from_global_ptr(globchanp, task::builder) {|po|
|
||||
let ch = comm::recv(po);
|
||||
comm::send(ch, true);
|
||||
let ch = comm::recv(po);
|
||||
comm::send(ch, true);
|
||||
}
|
||||
};
|
||||
// Talk to it
|
||||
let po = comm::port();
|
||||
|
@ -103,9 +105,11 @@ fn test_from_global_chan1() unsafe {
|
|||
assert comm::recv(po) == true;
|
||||
|
||||
// This one just reuses the previous channel
|
||||
let ch = chan_from_global_ptr(globchanp, task::builder) {|po|
|
||||
let ch = comm::recv(po);
|
||||
comm::send(ch, false);
|
||||
let ch = unsafe {
|
||||
chan_from_global_ptr(globchanp, task::builder) {|po|
|
||||
let ch = comm::recv(po);
|
||||
comm::send(ch, false);
|
||||
}
|
||||
};
|
||||
|
||||
// Talk to the original global task
|
||||
|
@ -115,7 +119,7 @@ fn test_from_global_chan1() unsafe {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_global_chan2() unsafe {
|
||||
fn test_from_global_chan2() {
|
||||
|
||||
iter::repeat(100u) {||
|
||||
// The global channel
|
||||
|
@ -129,12 +133,14 @@ fn test_from_global_chan2() unsafe {
|
|||
// create the global channel
|
||||
for uint::range(0u, 10u) {|i|
|
||||
task::spawn() {||
|
||||
let ch = chan_from_global_ptr(
|
||||
globchanp, task::builder) {|po|
|
||||
let ch = unsafe {
|
||||
chan_from_global_ptr(
|
||||
globchanp, task::builder) {|po|
|
||||
|
||||
for uint::range(0u, 10u) {|_j|
|
||||
let ch = comm::recv(po);
|
||||
comm::send(ch, {i});
|
||||
for uint::range(0u, 10u) {|_j|
|
||||
let ch = comm::recv(po);
|
||||
comm::send(ch, {i});
|
||||
}
|
||||
}
|
||||
};
|
||||
let po = comm::port();
|
||||
|
@ -174,62 +180,76 @@ This function is super-unsafe. Do not use.
|
|||
* Weak tasks must not be supervised. A supervised task keeps
|
||||
a reference to its parent, so the parent will not die.
|
||||
"]
|
||||
unsafe fn weaken_task(f: fn(comm::port<()>)) unsafe {
|
||||
unsafe fn weaken_task(f: fn(comm::port<()>)) {
|
||||
let po = comm::port();
|
||||
let ch = comm::chan(po);
|
||||
rustrt::rust_task_weaken(unsafe::reinterpret_cast(ch));
|
||||
unsafe {
|
||||
rustrt::rust_task_weaken(unsafe::reinterpret_cast(ch));
|
||||
}
|
||||
let _unweaken = unweaken(ch);
|
||||
f(po);
|
||||
|
||||
resource unweaken(ch: comm::chan<()>) unsafe {
|
||||
rustrt::rust_task_unweaken(unsafe::reinterpret_cast(ch));
|
||||
resource unweaken(ch: comm::chan<()>) {
|
||||
unsafe {
|
||||
rustrt::rust_task_unweaken(unsafe::reinterpret_cast(ch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weaken_task_then_unweaken() unsafe {
|
||||
fn test_weaken_task_then_unweaken() {
|
||||
task::try {||
|
||||
weaken_task {|_po|
|
||||
unsafe {
|
||||
weaken_task {|_po|
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weaken_task_wait() unsafe {
|
||||
fn test_weaken_task_wait() {
|
||||
let builder = task::builder();
|
||||
task::unsupervise(builder);
|
||||
task::run(builder) {||
|
||||
weaken_task {|po|
|
||||
comm::recv(po);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weaken_task_stress() unsafe {
|
||||
// Create a bunch of weak tasks
|
||||
iter::repeat(100u) {||
|
||||
task::spawn {||
|
||||
weaken_task {|_po|
|
||||
}
|
||||
}
|
||||
let builder = task::builder();
|
||||
task::unsupervise(builder);
|
||||
task::run(builder) {||
|
||||
unsafe {
|
||||
weaken_task {|po|
|
||||
// Wait for it to tell us to die
|
||||
comm::recv(po);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weaken_task_stress() {
|
||||
// Create a bunch of weak tasks
|
||||
iter::repeat(100u) {||
|
||||
task::spawn {||
|
||||
unsafe {
|
||||
weaken_task {|_po|
|
||||
}
|
||||
}
|
||||
}
|
||||
let builder = task::builder();
|
||||
task::unsupervise(builder);
|
||||
task::run(builder) {||
|
||||
unsafe {
|
||||
weaken_task {|po|
|
||||
// Wait for it to tell us to die
|
||||
comm::recv(po);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(windows))]
|
||||
fn test_weaken_task_fail() unsafe {
|
||||
fn test_weaken_task_fail() {
|
||||
let res = task::try {||
|
||||
weaken_task {|_po|
|
||||
fail;
|
||||
unsafe {
|
||||
weaken_task {|_po|
|
||||
fail;
|
||||
}
|
||||
}
|
||||
};
|
||||
assert result::is_err(res);
|
||||
|
|
|
@ -39,20 +39,26 @@ pure fn addr_of<T>(val: T) -> *T { unchecked { rusti::addr_of(val) } }
|
|||
|
||||
#[doc = "Get an unsafe mut pointer to a value"]
|
||||
#[inline(always)]
|
||||
pure fn mut_addr_of<T>(val: T) -> *mut T unsafe {
|
||||
unsafe::reinterpret_cast(rusti::addr_of(val))
|
||||
pure fn mut_addr_of<T>(val: T) -> *mut T {
|
||||
unsafe {
|
||||
unsafe::reinterpret_cast(rusti::addr_of(val))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Calculate the offset from a pointer"]
|
||||
#[inline(always)]
|
||||
fn offset<T>(ptr: *T, count: uint) -> *T unsafe {
|
||||
(ptr as uint + count * sys::size_of::<T>()) as *T
|
||||
fn offset<T>(ptr: *T, count: uint) -> *T {
|
||||
unsafe {
|
||||
(ptr as uint + count * sys::size_of::<T>()) as *T
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Calculate the offset from a const pointer"]
|
||||
#[inline(always)]
|
||||
fn const_offset<T>(ptr: *const T, count: uint) -> *const T unsafe {
|
||||
(ptr as uint + count * sys::size_of::<T>()) as *T
|
||||
fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
|
||||
unsafe {
|
||||
(ptr as uint + count * sys::size_of::<T>()) as *T
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Calculate the offset from a mut pointer"]
|
||||
|
@ -79,7 +85,7 @@ unsafe fn position<T>(buf: *T, f: fn(T) -> bool) -> uint {
|
|||
|
||||
#[doc = "Create an unsafe null pointer"]
|
||||
#[inline(always)]
|
||||
pure fn null<T>() -> *T unsafe { ret unsafe::reinterpret_cast(0u); }
|
||||
pure fn null<T>() -> *T { unsafe { unsafe::reinterpret_cast(0u) } }
|
||||
|
||||
#[doc = "Returns true if the pointer is equal to the null pointer."]
|
||||
pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }
|
||||
|
@ -127,48 +133,52 @@ impl extensions<T> for *T {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test() unsafe {
|
||||
type pair = {mut fst: int, mut snd: int};
|
||||
let p = {mut fst: 10, mut snd: 20};
|
||||
let pptr: *mut pair = mut_addr_of(p);
|
||||
let iptr: *mut int = unsafe::reinterpret_cast(pptr);
|
||||
assert (*iptr == 10);;
|
||||
*iptr = 30;
|
||||
assert (*iptr == 30);
|
||||
assert (p.fst == 30);;
|
||||
fn test() {
|
||||
unsafe {
|
||||
type pair = {mut fst: int, mut snd: int};
|
||||
let p = {mut fst: 10, mut snd: 20};
|
||||
let pptr: *mut pair = mut_addr_of(p);
|
||||
let iptr: *mut int = unsafe::reinterpret_cast(pptr);
|
||||
assert (*iptr == 10);;
|
||||
*iptr = 30;
|
||||
assert (*iptr == 30);
|
||||
assert (p.fst == 30);;
|
||||
|
||||
*pptr = {mut fst: 50, mut snd: 60};
|
||||
assert (*iptr == 50);
|
||||
assert (p.fst == 50);
|
||||
assert (p.snd == 60);
|
||||
*pptr = {mut fst: 50, mut snd: 60};
|
||||
assert (*iptr == 50);
|
||||
assert (p.fst == 50);
|
||||
assert (p.snd == 60);
|
||||
|
||||
let v0 = [32000u16, 32001u16, 32002u16];
|
||||
let v1 = [0u16, 0u16, 0u16];
|
||||
let v0 = [32000u16, 32001u16, 32002u16];
|
||||
let v1 = [0u16, 0u16, 0u16];
|
||||
|
||||
ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
|
||||
ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
|
||||
assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
|
||||
ptr::memcpy(vec::unsafe::to_ptr(v1),
|
||||
ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
|
||||
assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
|
||||
ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
|
||||
vec::unsafe::to_ptr(v0), 1u);
|
||||
assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
|
||||
ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
|
||||
ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
|
||||
assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
|
||||
ptr::memcpy(vec::unsafe::to_ptr(v1),
|
||||
ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
|
||||
assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
|
||||
ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
|
||||
vec::unsafe::to_ptr(v0), 1u);
|
||||
assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_position() unsafe {
|
||||
fn test_position() {
|
||||
import str::as_c_str;
|
||||
import libc::c_char;
|
||||
|
||||
let s = "hello";
|
||||
assert 2u == as_c_str(s) {|p| position(p) {|c| c == 'l' as c_char} };
|
||||
assert 4u == as_c_str(s) {|p| position(p) {|c| c == 'o' as c_char} };
|
||||
assert 5u == as_c_str(s) {|p| position(p) {|c| c == 0 as c_char } };
|
||||
unsafe {
|
||||
assert 2u == as_c_str(s) {|p| position(p) {|c| c == 'l' as c_char} };
|
||||
assert 4u == as_c_str(s) {|p| position(p) {|c| c == 'o' as c_char} };
|
||||
assert 5u == as_c_str(s) {|p| position(p) {|c| c == 0 as c_char } };
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buf_len() unsafe {
|
||||
fn test_buf_len() {
|
||||
let s0 = "hello";
|
||||
let s1 = "there";
|
||||
let s2 = "thing";
|
||||
|
@ -177,7 +187,7 @@ fn test_buf_len() unsafe {
|
|||
str::as_c_str(s2) {|p2|
|
||||
let v = [p0, p1, p2, null()];
|
||||
vec::as_buf(v) {|vp|
|
||||
assert buf_len(vp) == 3u;
|
||||
assert unsafe { buf_len(vp) } == 3u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -326,14 +326,16 @@ fn iter_vec2<S,T,U:copy>(ss: [S], ts: [T],
|
|||
#[doc="
|
||||
Unwraps a result, assuming it is an `ok(T)`
|
||||
"]
|
||||
fn unwrap<T, U>(-res: result<T, U>) -> T unsafe {
|
||||
let addr = alt res {
|
||||
ok(x) { ptr::addr_of(x) }
|
||||
err(_) { fail "error result" }
|
||||
};
|
||||
let liberated_value = unsafe::reinterpret_cast(*addr);
|
||||
unsafe::forget(res);
|
||||
ret liberated_value;
|
||||
fn unwrap<T, U>(-res: result<T, U>) -> T {
|
||||
unsafe {
|
||||
let addr = alt res {
|
||||
ok(x) { ptr::addr_of(x) }
|
||||
err(_) { fail "error result" }
|
||||
};
|
||||
let liberated_value = unsafe::reinterpret_cast(*addr);
|
||||
unsafe::forget(res);
|
||||
ret liberated_value;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -66,7 +66,7 @@ fn spawn_process(prog: str, args: [str],
|
|||
env: option<[(str,str)]>,
|
||||
dir: option<str>,
|
||||
in_fd: c_int, out_fd: c_int, err_fd: c_int)
|
||||
-> pid_t unsafe {
|
||||
-> pid_t {
|
||||
with_argv(prog, args) {|argv|
|
||||
with_envp(env) { |envp|
|
||||
with_dirp(dir) { |dirp|
|
||||
|
@ -78,7 +78,7 @@ fn spawn_process(prog: str, args: [str],
|
|||
}
|
||||
|
||||
fn with_argv<T>(prog: str, args: [str],
|
||||
cb: fn(**libc::c_char) -> T) -> T unsafe {
|
||||
cb: fn(**libc::c_char) -> T) -> T {
|
||||
let mut argptrs = str::as_c_str(prog) {|b| [b] };
|
||||
let mut tmps = [];
|
||||
for vec::each(args) {|arg|
|
||||
|
@ -92,7 +92,7 @@ fn with_argv<T>(prog: str, args: [str],
|
|||
|
||||
#[cfg(unix)]
|
||||
fn with_envp<T>(env: option<[(str,str)]>,
|
||||
cb: fn(*c_void) -> T) -> T unsafe {
|
||||
cb: fn(*c_void) -> T) -> T {
|
||||
// On posixy systems we can pass a char** for envp, which is
|
||||
// a null-terminated array of "k=v\n" strings.
|
||||
alt env {
|
||||
|
@ -107,7 +107,9 @@ fn with_envp<T>(env: option<[(str,str)]>,
|
|||
ptrs += str::as_c_str(*t) {|b| [b]};
|
||||
}
|
||||
ptrs += [ptr::null()];
|
||||
vec::as_buf(ptrs) { |p| cb(::unsafe::reinterpret_cast(p)) }
|
||||
vec::as_buf(ptrs) { |p|
|
||||
unsafe { cb(::unsafe::reinterpret_cast(p)) }
|
||||
}
|
||||
}
|
||||
_ {
|
||||
cb(ptr::null())
|
||||
|
@ -117,31 +119,33 @@ fn with_envp<T>(env: option<[(str,str)]>,
|
|||
|
||||
#[cfg(windows)]
|
||||
fn with_envp<T>(env: option<[(str,str)]>,
|
||||
cb: fn(*c_void) -> T) -> T unsafe {
|
||||
cb: fn(*c_void) -> T) -> T {
|
||||
// On win32 we pass an "environment block" which is not a char**, but
|
||||
// rather a concatenation of null-terminated k=v\0 sequences, with a final
|
||||
// \0 to terminate.
|
||||
alt env {
|
||||
some(es) if !vec::is_empty(es) {
|
||||
let mut blk : [u8] = [];
|
||||
for vec::each(es) {|e|
|
||||
let (k,v) = e;
|
||||
let t = #fmt("%s=%s", k, v);
|
||||
let mut v : [u8] = ::unsafe::reinterpret_cast(t);
|
||||
blk += v;
|
||||
::unsafe::forget(v);
|
||||
unsafe {
|
||||
alt env {
|
||||
some(es) if !vec::is_empty(es) {
|
||||
let mut blk : [u8] = [];
|
||||
for vec::each(es) {|e|
|
||||
let (k,v) = e;
|
||||
let t = #fmt("%s=%s", k, v);
|
||||
let mut v : [u8] = ::unsafe::reinterpret_cast(t);
|
||||
blk += v;
|
||||
::unsafe::forget(v);
|
||||
}
|
||||
blk += [0_u8];
|
||||
vec::as_buf(blk) {|p| cb(::unsafe::reinterpret_cast(p)) }
|
||||
}
|
||||
_ {
|
||||
cb(ptr::null())
|
||||
}
|
||||
}
|
||||
blk += [0_u8];
|
||||
vec::as_buf(blk) {|p| cb(::unsafe::reinterpret_cast(p)) }
|
||||
}
|
||||
_ {
|
||||
cb(ptr::null())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn with_dirp<T>(d: option<str>,
|
||||
cb: fn(*libc::c_char) -> T) -> T unsafe {
|
||||
cb: fn(*libc::c_char) -> T) -> T {
|
||||
alt d {
|
||||
some(dir) { str::as_c_str(dir, cb) }
|
||||
none { cb(ptr::null()) }
|
||||
|
|
|
@ -122,9 +122,9 @@ Convert a vector of bytes to a UTF-8 string
|
|||
|
||||
Fails if invalid UTF-8
|
||||
"]
|
||||
pure fn from_bytes(vv: [u8]) -> str unsafe {
|
||||
assert is_utf8(vv);
|
||||
ret unsafe::from_bytes(vv);
|
||||
pure fn from_bytes(vv: [u8]) -> str {
|
||||
assert is_utf8(vv);
|
||||
ret unsafe { unsafe::from_bytes(vv) };
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
|
@ -134,83 +134,85 @@ Convert a byte to a UTF-8 string
|
|||
|
||||
Fails if invalid UTF-8
|
||||
"]
|
||||
pure fn from_byte(b: u8) -> str unsafe {
|
||||
pure fn from_byte(b: u8) -> str {
|
||||
assert b < 128u8;
|
||||
let mut v = [b, 0u8];
|
||||
::unsafe::transmute(v)
|
||||
unsafe { ::unsafe::transmute(v) }
|
||||
}
|
||||
|
||||
#[doc = "Appends a character at the end of a string"]
|
||||
fn push_char(&s: str, ch: char) unsafe {
|
||||
let code = ch as uint;
|
||||
let nb = if code < max_one_b { 1u }
|
||||
fn push_char(&s: str, ch: char) {
|
||||
unsafe {
|
||||
let code = ch as uint;
|
||||
let nb = if code < max_one_b { 1u }
|
||||
else if code < max_two_b { 2u }
|
||||
else if code < max_three_b { 3u }
|
||||
else if code < max_four_b { 4u }
|
||||
else if code < max_five_b { 5u }
|
||||
else { 6u };
|
||||
let len = len(s);
|
||||
let new_len = len + nb;
|
||||
reserve_at_least(s, new_len);
|
||||
let off = len;
|
||||
as_buf(s) {|buf|
|
||||
let buf: *mut u8 = ::unsafe::reinterpret_cast(buf);
|
||||
if nb == 1u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
code as u8;
|
||||
} else if nb == 2u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 6u & 31u | tag_two_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
} else if nb == 3u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 12u & 15u | tag_three_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code >> 6u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 2u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
} else if nb == 4u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 18u & 7u | tag_four_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code >> 12u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 2u) =
|
||||
(code >> 6u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 3u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
} else if nb == 5u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 24u & 3u | tag_five_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code >> 18u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 2u) =
|
||||
(code >> 12u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 3u) =
|
||||
(code >> 6u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 4u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
} else if nb == 6u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 30u & 1u | tag_six_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code >> 24u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 2u) =
|
||||
(code >> 18u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 3u) =
|
||||
(code >> 12u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 4u) =
|
||||
(code >> 6u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 5u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
let len = len(s);
|
||||
let new_len = len + nb;
|
||||
reserve_at_least(s, new_len);
|
||||
let off = len;
|
||||
as_buf(s) {|buf|
|
||||
let buf: *mut u8 = ::unsafe::reinterpret_cast(buf);
|
||||
if nb == 1u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
code as u8;
|
||||
} else if nb == 2u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 6u & 31u | tag_two_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
} else if nb == 3u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 12u & 15u | tag_three_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code >> 6u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 2u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
} else if nb == 4u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 18u & 7u | tag_four_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code >> 12u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 2u) =
|
||||
(code >> 6u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 3u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
} else if nb == 5u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 24u & 3u | tag_five_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code >> 18u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 2u) =
|
||||
(code >> 12u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 3u) =
|
||||
(code >> 6u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 4u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
} else if nb == 6u {
|
||||
*ptr::mut_offset(buf, off) =
|
||||
(code >> 30u & 1u | tag_six_b) as u8;
|
||||
*ptr::mut_offset(buf, off + 1u) =
|
||||
(code >> 24u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 2u) =
|
||||
(code >> 18u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 3u) =
|
||||
(code >> 12u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 4u) =
|
||||
(code >> 6u & 63u | tag_cont) as u8;
|
||||
*ptr::mut_offset(buf, off + 5u) =
|
||||
(code & 63u | tag_cont) as u8;
|
||||
}
|
||||
*ptr::mut_offset(buf, off + nb) = 0u8;
|
||||
}
|
||||
*ptr::mut_offset(buf, off + nb) = 0u8;
|
||||
}
|
||||
|
||||
as_bytes(s) {|bytes|
|
||||
let mut mut_bytes: [u8] = ::unsafe::reinterpret_cast(bytes);
|
||||
vec::unsafe::set_len(mut_bytes, new_len + 1u);
|
||||
::unsafe::forget(mut_bytes);
|
||||
as_bytes(s) {|bytes|
|
||||
let mut mut_bytes: [u8] = ::unsafe::reinterpret_cast(bytes);
|
||||
vec::unsafe::set_len(mut_bytes, new_len + 1u);
|
||||
::unsafe::forget(mut_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,9 +278,9 @@ Remove the first character from a string and return it
|
|||
|
||||
If the string does not contain any characters
|
||||
"]
|
||||
fn shift_char(&s: str) -> char unsafe {
|
||||
fn shift_char(&s: str) -> char {
|
||||
let {ch, next} = char_range_at(s, 0u);
|
||||
s = unsafe::slice_bytes(s, next, len(s));
|
||||
s = unsafe { unsafe::slice_bytes(s, next, len(s)) };
|
||||
ret ch;
|
||||
}
|
||||
|
||||
|
@ -320,20 +322,22 @@ Converts a string to a vector of bytes
|
|||
|
||||
The result vector is not null-terminated.
|
||||
"]
|
||||
pure fn bytes(s: str) -> [u8] unsafe {
|
||||
let mut s_copy = s;
|
||||
let mut v: [u8] = ::unsafe::transmute(s_copy);
|
||||
vec::unsafe::set_len(v, len(s));
|
||||
ret v;
|
||||
pure fn bytes(s: str) -> [u8] {
|
||||
unsafe {
|
||||
let mut s_copy = s;
|
||||
let mut v: [u8] = ::unsafe::transmute(s_copy);
|
||||
vec::unsafe::set_len(v, len(s));
|
||||
ret v;
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Work with the string as a byte slice, not including trailing null.
|
||||
"]
|
||||
#[inline(always)]
|
||||
pure fn byte_slice<T>(s: str/&, f: fn([u8]/&) -> T) -> T unsafe {
|
||||
pure fn byte_slice<T>(s: str/&, f: fn([u8]/&) -> T) -> T {
|
||||
unpack_slice(s) {|p,n|
|
||||
vec::unsafe::form_slice(p, n-1u, f)
|
||||
unsafe { vec::unsafe::form_slice(p, n-1u, f) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,10 +369,10 @@ Returns a slice of the given string from the byte range [`begin`..`end`)
|
|||
Fails when `begin` and `end` do not point to valid characters or
|
||||
beyond the last character of the string
|
||||
"]
|
||||
pure fn slice(s: str/&, begin: uint, end: uint) -> str unsafe {
|
||||
pure fn slice(s: str/&, begin: uint, end: uint) -> str {
|
||||
assert is_char_boundary(s, begin);
|
||||
assert is_char_boundary(s, end);
|
||||
unsafe::slice_bytes(s, begin, end)
|
||||
unsafe { unsafe::slice_bytes(s, begin, end) }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
|
@ -396,7 +400,7 @@ pure fn split_char_nonempty(s: str/&, sep: char) -> [str] {
|
|||
}
|
||||
|
||||
pure fn split_char_inner(s: str/&, sep: char, count: uint, allow_empty: bool)
|
||||
-> [str] unsafe {
|
||||
-> [str] {
|
||||
if sep < 128u as char {
|
||||
let b = sep as u8, l = len(s);
|
||||
let mut result = [], done = 0u;
|
||||
|
@ -404,7 +408,7 @@ pure fn split_char_inner(s: str/&, sep: char, count: uint, allow_empty: bool)
|
|||
while i < l && done < count {
|
||||
if s[i] == b {
|
||||
if allow_empty || start < i {
|
||||
result += [unsafe::slice_bytes(s, start, i)];
|
||||
result += [unsafe { unsafe::slice_bytes(s, start, i) }];
|
||||
}
|
||||
start = i + 1u;
|
||||
done += 1u;
|
||||
|
@ -412,7 +416,7 @@ pure fn split_char_inner(s: str/&, sep: char, count: uint, allow_empty: bool)
|
|||
i += 1u;
|
||||
}
|
||||
if allow_empty || start < l {
|
||||
result += [unsafe::slice_bytes(s, start, l)];
|
||||
result += [unsafe { unsafe::slice_bytes(s, start, l) }];
|
||||
}
|
||||
result
|
||||
} else {
|
||||
|
@ -440,14 +444,14 @@ pure fn split_nonempty(s: str/&, sepfn: fn(char) -> bool) -> [str] {
|
|||
}
|
||||
|
||||
pure fn split_inner(s: str/&, sepfn: fn(cc: char) -> bool, count: uint,
|
||||
allow_empty: bool) -> [str] unsafe {
|
||||
allow_empty: bool) -> [str] {
|
||||
let l = len(s);
|
||||
let mut result = [], i = 0u, start = 0u, done = 0u;
|
||||
while i < l && done < count {
|
||||
let {ch, next} = char_range_at(s, i);
|
||||
if sepfn(ch) {
|
||||
if allow_empty || start < i {
|
||||
result += [unsafe::slice_bytes(s, start, i)];
|
||||
result += [unsafe { unsafe::slice_bytes(s, start, i) }];
|
||||
}
|
||||
start = next;
|
||||
done += 1u;
|
||||
|
@ -455,7 +459,7 @@ pure fn split_inner(s: str/&, sepfn: fn(cc: char) -> bool, count: uint,
|
|||
i = next;
|
||||
}
|
||||
if allow_empty || start < l {
|
||||
result += [unsafe::slice_bytes(s, start, l)];
|
||||
result += [unsafe { unsafe::slice_bytes(s, start, l) }];
|
||||
}
|
||||
result
|
||||
}
|
||||
|
@ -578,7 +582,7 @@ Replace all occurrences of one string with another
|
|||
|
||||
The original string with all occurances of `from` replaced with `to`
|
||||
"]
|
||||
pure fn replace(s: str, from: str, to: str) -> str unsafe {
|
||||
pure fn replace(s: str, from: str, to: str) -> str {
|
||||
let mut result = "", first = true;
|
||||
iter_between_matches(s, from) {|start, end|
|
||||
if first { first = false; } else { result += to; }
|
||||
|
@ -709,7 +713,7 @@ Apply a function to each substring after splitting by character, up to
|
|||
`count` times
|
||||
"]
|
||||
pure fn splitn_char_iter(ss: str/&, sep: char, count: uint,
|
||||
ff: fn(&&str)) unsafe {
|
||||
ff: fn(&&str)) {
|
||||
vec::iter(splitn_char(ss, sep, count), ff)
|
||||
}
|
||||
|
||||
|
@ -1149,7 +1153,7 @@ Returns true if one string starts with another
|
|||
* haystack - The string to look in
|
||||
* needle - The string to look for
|
||||
"]
|
||||
pure fn starts_with(haystack: str/&a, needle: str/&b) -> bool unsafe {
|
||||
pure fn starts_with(haystack: str/&a, needle: str/&b) -> bool {
|
||||
let haystack_len = len(haystack), needle_len = len(needle);
|
||||
if needle_len == 0u { true }
|
||||
else if needle_len > haystack_len { false }
|
||||
|
@ -1564,9 +1568,11 @@ interop.
|
|||
let i = str::as_bytes(\"Hello World\") { |bytes| vec::len(bytes) };
|
||||
~~~
|
||||
"]
|
||||
pure fn as_bytes<T>(s: str, f: fn([u8]) -> T) -> T unsafe {
|
||||
let v: *[u8] = ::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
f(*v)
|
||||
pure fn as_bytes<T>(s: str, f: fn([u8]) -> T) -> T {
|
||||
unsafe {
|
||||
let v: *[u8] = ::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
f(*v)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
|
@ -1575,8 +1581,8 @@ Work with the byte buffer of a string.
|
|||
Allows for unsafe manipulation of strings, which is useful for native
|
||||
interop.
|
||||
"]
|
||||
pure fn as_buf<T>(s: str, f: fn(*u8) -> T) -> T unsafe {
|
||||
as_bytes(s) { |v| vec::as_buf(v, f) }
|
||||
pure fn as_buf<T>(s: str, f: fn(*u8) -> T) -> T {
|
||||
as_bytes(s) { |v| unsafe { vec::as_buf(v, f) } }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
|
@ -1591,7 +1597,7 @@ interop, without copying the original string.
|
|||
let s = str::as_buf(\"PATH\", { |path_buf| libc::getenv(path_buf) });
|
||||
~~~
|
||||
"]
|
||||
pure fn as_c_str<T>(s: str, f: fn(*libc::c_char) -> T) -> T unsafe {
|
||||
pure fn as_c_str<T>(s: str, f: fn(*libc::c_char) -> T) -> T {
|
||||
as_buf(s) {|buf| f(buf as *libc::c_char) }
|
||||
}
|
||||
|
||||
|
@ -1605,10 +1611,12 @@ indexable area for a null byte, as is the case in slices pointing
|
|||
to full strings, or suffixes of them.
|
||||
"]
|
||||
#[inline(always)]
|
||||
pure fn unpack_slice<T>(s: str/&, f: fn(*u8, uint) -> T) -> T unsafe {
|
||||
let v : *(*u8,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
let (buf,len) = *v;
|
||||
f(buf, len)
|
||||
pure fn unpack_slice<T>(s: str/&, f: fn(*u8, uint) -> T) -> T {
|
||||
unsafe {
|
||||
let v : *(*u8,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
let (buf,len) = *v;
|
||||
f(buf, len)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
|
@ -1653,7 +1661,7 @@ capacity, then no action is taken.
|
|||
* s - A string
|
||||
* n - The number of bytes to reserve space for
|
||||
"]
|
||||
fn reserve_at_least(&s: str, n: uint) unsafe {
|
||||
fn reserve_at_least(&s: str, n: uint) {
|
||||
reserve(s, uint::next_power_of_two(n + 1u) - 1u)
|
||||
}
|
||||
|
||||
|
@ -1661,7 +1669,7 @@ fn reserve_at_least(&s: str, n: uint) unsafe {
|
|||
Returns the number of single-byte characters the string can hold without
|
||||
reallocating
|
||||
"]
|
||||
pure fn capacity(&&s: str) -> uint unsafe {
|
||||
pure fn capacity(&&s: str) -> uint {
|
||||
as_bytes(s) {|buf|
|
||||
let vcap = vec::capacity(buf);
|
||||
assert vcap > 0u;
|
||||
|
@ -1742,10 +1750,12 @@ mod unsafe {
|
|||
|
||||
Does not verify that the vector contains valid UTF-8.
|
||||
"]
|
||||
unsafe fn from_bytes(v: [const u8]) -> str unsafe {
|
||||
let mut vcopy : [u8] = ::unsafe::transmute(copy v);
|
||||
vec::push(vcopy, 0u8);
|
||||
::unsafe::transmute(vcopy)
|
||||
unsafe fn from_bytes(v: [const u8]) -> str {
|
||||
unsafe {
|
||||
let mut vcopy : [u8] = ::unsafe::transmute(copy v);
|
||||
vec::push(vcopy, 0u8);
|
||||
::unsafe::transmute(vcopy)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
|
@ -1765,20 +1775,22 @@ mod unsafe {
|
|||
If begin is greater than end.
|
||||
If end is greater than the length of the string.
|
||||
"]
|
||||
unsafe fn slice_bytes(s: str/&, begin: uint, end: uint) -> str unsafe {
|
||||
unsafe fn slice_bytes(s: str/&, begin: uint, end: uint) -> str {
|
||||
unpack_slice(s) { |sbuf, n|
|
||||
assert (begin <= end);
|
||||
assert (end <= n);
|
||||
|
||||
let mut v = [];
|
||||
vec::reserve(v, end - begin + 1u);
|
||||
vec::as_buf(v) { |vbuf|
|
||||
let src = ptr::offset(sbuf, begin);
|
||||
ptr::memcpy(vbuf, src, end - begin);
|
||||
unsafe {
|
||||
vec::as_buf(v) { |vbuf|
|
||||
let src = ptr::offset(sbuf, begin);
|
||||
ptr::memcpy(vbuf, src, end - begin);
|
||||
}
|
||||
vec::unsafe::set_len(v, end - begin);
|
||||
v += [0u8];
|
||||
::unsafe::transmute(v)
|
||||
}
|
||||
vec::unsafe::set_len(v, end - begin);
|
||||
v += [0u8];
|
||||
::unsafe::transmute(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1795,22 +1807,22 @@ mod unsafe {
|
|||
#[doc = "
|
||||
Removes the last byte from a string and returns it. (Not UTF-8 safe).
|
||||
"]
|
||||
unsafe fn pop_byte(&s: str) -> u8 unsafe {
|
||||
unsafe fn pop_byte(&s: str) -> u8 {
|
||||
let len = len(s);
|
||||
assert (len > 0u);
|
||||
let b = s[len - 1u];
|
||||
set_len(s, len - 1u);
|
||||
unsafe { set_len(s, len - 1u) };
|
||||
ret b;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Removes the first byte from a string and returns it. (Not UTF-8 safe).
|
||||
"]
|
||||
unsafe fn shift_byte(&s: str) -> u8 unsafe {
|
||||
unsafe fn shift_byte(&s: str) -> u8 {
|
||||
let len = len(s);
|
||||
assert (len > 0u);
|
||||
let b = s[0];
|
||||
s = unsafe::slice_bytes(s, 1u, len);
|
||||
s = unsafe { unsafe::slice_bytes(s, 1u, len) };
|
||||
ret b;
|
||||
}
|
||||
|
||||
|
@ -1825,11 +1837,13 @@ mod unsafe {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_buf_len() unsafe {
|
||||
let a = [65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
|
||||
let b = vec::unsafe::to_ptr(a);
|
||||
let c = from_buf_len(b, 3u);
|
||||
assert (c == "AAA");
|
||||
fn test_from_buf_len() {
|
||||
unsafe {
|
||||
let a = [65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
|
||||
let b = vec::unsafe::to_ptr(a);
|
||||
let c = from_buf_len(b, 3u);
|
||||
assert (c == "AAA");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2274,24 +2288,27 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsafe_slice() unsafe {
|
||||
assert (eq("ab", unsafe::slice_bytes("abc", 0u, 2u)));
|
||||
assert (eq("bc", unsafe::slice_bytes("abc", 1u, 3u)));
|
||||
assert (eq("", unsafe::slice_bytes("abc", 1u, 1u)));
|
||||
fn a_million_letter_a() -> str {
|
||||
let mut i = 0;
|
||||
let mut rs = "";
|
||||
while i < 100000 { rs += "aaaaaaaaaa"; i += 1; }
|
||||
ret rs;
|
||||
fn test_unsafe_slice() {
|
||||
unsafe {
|
||||
assert (eq("ab", unsafe::slice_bytes("abc", 0u, 2u)));
|
||||
assert (eq("bc", unsafe::slice_bytes("abc", 1u, 3u)));
|
||||
assert (eq("", unsafe::slice_bytes("abc", 1u, 1u)));
|
||||
fn a_million_letter_a() -> str {
|
||||
let mut i = 0;
|
||||
let mut rs = "";
|
||||
while i < 100000 { rs += "aaaaaaaaaa"; i += 1; }
|
||||
ret rs;
|
||||
}
|
||||
fn half_a_million_letter_a() -> str {
|
||||
let mut i = 0;
|
||||
let mut rs = "";
|
||||
while i < 100000 { rs += "aaaaa"; i += 1; }
|
||||
ret rs;
|
||||
}
|
||||
assert eq(half_a_million_letter_a(),
|
||||
unsafe::slice_bytes(a_million_letter_a(),
|
||||
0u, 500000u));
|
||||
}
|
||||
fn half_a_million_letter_a() -> str {
|
||||
let mut i = 0;
|
||||
let mut rs = "";
|
||||
while i < 100000 { rs += "aaaaa"; i += 1; }
|
||||
ret rs;
|
||||
}
|
||||
assert (eq(half_a_million_letter_a(),
|
||||
unsafe::slice_bytes(a_million_letter_a(), 0u, 500000u)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2483,25 +2500,25 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_shift_byte() unsafe {
|
||||
fn test_shift_byte() {
|
||||
let mut s = "ABC";
|
||||
let b = unsafe::shift_byte(s);
|
||||
let b = unsafe { unsafe::shift_byte(s) };
|
||||
assert (s == "BC");
|
||||
assert (b == 65u8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pop_byte() unsafe {
|
||||
fn test_pop_byte() {
|
||||
let mut s = "ABC";
|
||||
let b = unsafe::pop_byte(s);
|
||||
let b = unsafe { unsafe::pop_byte(s) };
|
||||
assert (s == "AB");
|
||||
assert (b == 67u8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsafe_from_bytes() unsafe {
|
||||
fn test_unsafe_from_bytes() {
|
||||
let a = [65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8];
|
||||
let b = unsafe::from_bytes(a);
|
||||
let b = unsafe { unsafe::from_bytes(a) };
|
||||
assert (b == "AAAAAAA");
|
||||
}
|
||||
|
||||
|
@ -2541,11 +2558,13 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_buf() unsafe {
|
||||
let a = [65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
|
||||
let b = vec::unsafe::to_ptr(a);
|
||||
let c = unsafe::from_buf(b);
|
||||
assert (c == "AAAAAAA");
|
||||
fn test_from_buf() {
|
||||
unsafe {
|
||||
let a = [65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
|
||||
let b = vec::unsafe::to_ptr(a);
|
||||
let c = unsafe::from_buf(b);
|
||||
assert (c == "AAAAAAA");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2557,25 +2576,33 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_as_buf() unsafe {
|
||||
fn test_as_buf() {
|
||||
let a = "Abcdefg";
|
||||
let b = as_buf(a, {|buf| assert (*buf == 65u8); 100 });
|
||||
let b = as_buf(a, {|buf|
|
||||
assert unsafe { *buf } == 65u8;
|
||||
100
|
||||
});
|
||||
assert (b == 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_as_buf_small() unsafe {
|
||||
fn test_as_buf_small() {
|
||||
let a = "A";
|
||||
let b = as_buf(a, {|buf| assert (*buf == 65u8); 100 });
|
||||
let b = as_buf(a, {|buf|
|
||||
assert unsafe { *buf } == 65u8;
|
||||
100
|
||||
});
|
||||
assert (b == 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_as_buf2() unsafe {
|
||||
let s = "hello";
|
||||
let sb = as_buf(s, {|b| b });
|
||||
let s_cstr = unsafe::from_buf(sb);
|
||||
assert (eq(s_cstr, s));
|
||||
fn test_as_buf2() {
|
||||
unsafe {
|
||||
let s = "hello";
|
||||
let sb = as_buf(s, {|b| b });
|
||||
let s_cstr = unsafe::from_buf(sb);
|
||||
assert (eq(s_cstr, s));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2813,14 +2840,16 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_unpack_slice() unsafe {
|
||||
fn test_unpack_slice() {
|
||||
let a = "hello";
|
||||
unpack_slice(a) {|buf, len|
|
||||
assert a[0] == 'h' as u8;
|
||||
assert *buf == 'h' as u8;
|
||||
assert len == 6u;
|
||||
assert *ptr::offset(buf,4u) == 'o' as u8;
|
||||
assert *ptr::offset(buf,5u) == 0u8;
|
||||
unsafe {
|
||||
assert a[0] == 'h' as u8;
|
||||
assert *buf == 'h' as u8;
|
||||
assert len == 6u;
|
||||
assert *ptr::offset(buf,4u) == 'o' as u8;
|
||||
assert *ptr::offset(buf,5u) == 0u8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ pure fn get_type_desc<T>() -> *type_desc {
|
|||
|
||||
#[doc = "Returns the size of a type"]
|
||||
#[inline(always)]
|
||||
pure fn size_of<T>() -> uint unsafe {
|
||||
pure fn size_of<T>() -> uint {
|
||||
unchecked { rusti::size_of::<T>() }
|
||||
}
|
||||
|
||||
|
@ -62,12 +62,12 @@ Returns the ABI-required minimum alignment of a type
|
|||
This is the alignment used for struct fields. It may be smaller
|
||||
than the preferred alignment.
|
||||
"]
|
||||
pure fn min_align_of<T>() -> uint unsafe {
|
||||
pure fn min_align_of<T>() -> uint {
|
||||
unchecked { rusti::min_align_of::<T>() }
|
||||
}
|
||||
|
||||
#[doc = "Returns the preferred alignment of a type"]
|
||||
pure fn pref_align_of<T>() -> uint unsafe {
|
||||
pure fn pref_align_of<T>() -> uint {
|
||||
unchecked { rusti::pref_align_of::<T>() }
|
||||
}
|
||||
|
||||
|
|
|
@ -501,7 +501,7 @@ type task_id = int;
|
|||
type rust_task = libc::c_void;
|
||||
type rust_closure = libc::c_void;
|
||||
|
||||
fn spawn_raw(opts: task_opts, +f: fn~()) unsafe {
|
||||
fn spawn_raw(opts: task_opts, +f: fn~()) {
|
||||
|
||||
let mut f = if opts.supervise {
|
||||
f
|
||||
|
@ -516,26 +516,28 @@ fn spawn_raw(opts: task_opts, +f: fn~()) unsafe {
|
|||
}
|
||||
};
|
||||
|
||||
let fptr = ptr::addr_of(f);
|
||||
let closure: *rust_closure = unsafe::reinterpret_cast(fptr);
|
||||
unsafe {
|
||||
let fptr = ptr::addr_of(f);
|
||||
let closure: *rust_closure = unsafe::reinterpret_cast(fptr);
|
||||
|
||||
let new_task = alt opts.sched {
|
||||
none {
|
||||
rustrt::new_task()
|
||||
}
|
||||
some(sched_opts) {
|
||||
new_task_in_new_sched(sched_opts)
|
||||
}
|
||||
};
|
||||
let new_task = alt opts.sched {
|
||||
none {
|
||||
rustrt::new_task()
|
||||
}
|
||||
some(sched_opts) {
|
||||
new_task_in_new_sched(sched_opts)
|
||||
}
|
||||
};
|
||||
|
||||
option::iter(opts.notify_chan) {|c|
|
||||
// FIXME (#1087): Would like to do notification in Rust
|
||||
rustrt::rust_task_config_notify(new_task, c);
|
||||
option::iter(opts.notify_chan) {|c|
|
||||
// FIXME (#1087): Would like to do notification in Rust
|
||||
rustrt::rust_task_config_notify(new_task, c);
|
||||
}
|
||||
|
||||
rustrt::start_task(new_task, closure);
|
||||
unsafe::forget(f);
|
||||
}
|
||||
|
||||
rustrt::start_task(new_task, closure);
|
||||
unsafe::forget(f);
|
||||
|
||||
fn new_task_in_new_sched(opts: sched_opts) -> *rust_task {
|
||||
if opts.native_stack_size != none {
|
||||
fail "native_stack_size scheduler option unimplemented";
|
||||
|
@ -959,7 +961,7 @@ fn test_osmain() {
|
|||
#[test]
|
||||
#[ignore(cfg(windows))]
|
||||
#[should_fail]
|
||||
fn test_unkillable() unsafe {
|
||||
fn test_unkillable() {
|
||||
import comm::methods;
|
||||
let po = comm::port();
|
||||
let ch = po.chan();
|
||||
|
@ -977,14 +979,16 @@ fn test_unkillable() unsafe {
|
|||
fail;
|
||||
}
|
||||
|
||||
unkillable {||
|
||||
let p = ~0;
|
||||
let pp: *uint = unsafe::transmute(p);
|
||||
unsafe {
|
||||
unkillable {||
|
||||
let p = ~0;
|
||||
let pp: *uint = unsafe::transmute(p);
|
||||
|
||||
// If we are killed here then the box will leak
|
||||
po.recv();
|
||||
// If we are killed here then the box will leak
|
||||
po.recv();
|
||||
|
||||
let _p: ~int = unsafe::transmute(pp);
|
||||
let _p: ~int = unsafe::transmute(pp);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can be killed
|
||||
|
|
|
@ -131,17 +131,17 @@ Convert to a string in a given base
|
|||
|
||||
Fails if `radix` < 2 or `radix` > 16
|
||||
"]
|
||||
fn to_str(num: T, radix: uint) -> str unsafe {
|
||||
fn to_str(num: T, radix: uint) -> str {
|
||||
to_str_bytes(false, num, radix) {|slice|
|
||||
vec::unpack_slice(slice) {|p, len|
|
||||
str::unsafe::from_buf_len(p, len)
|
||||
unsafe { str::unsafe::from_buf_len(p, len) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Low-level helper routine for string conversion."]
|
||||
fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
|
||||
f: fn([u8]/&) -> U) -> U unsafe {
|
||||
f: fn([u8]/&) -> U) -> U {
|
||||
|
||||
#[inline(always)]
|
||||
fn digit(n: T) -> u8 {
|
||||
|
@ -177,28 +177,30 @@ fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
|
|||
// pointers and unsafe bits, and the codegen will prove it's all
|
||||
// in-bounds, no extra cost.
|
||||
|
||||
vec::unpack_slice(buf) {|p, len|
|
||||
let mp = p as *mut u8;
|
||||
let mut i = len;
|
||||
let mut n = num;
|
||||
let radix = radix as T;
|
||||
loop {
|
||||
i -= 1u;
|
||||
unsafe {
|
||||
vec::unpack_slice(buf) {|p, len|
|
||||
let mp = p as *mut u8;
|
||||
let mut i = len;
|
||||
let mut n = num;
|
||||
let radix = radix as T;
|
||||
loop {
|
||||
i -= 1u;
|
||||
assert 0u < i && i < len;
|
||||
*ptr::mut_offset(mp, i) = digit(n % radix);
|
||||
n /= radix;
|
||||
if n == 0 as T { break; }
|
||||
}
|
||||
|
||||
assert 0u < i && i < len;
|
||||
*ptr::mut_offset(mp, i) = digit(n % radix);
|
||||
n /= radix;
|
||||
if n == 0 as T { break; }
|
||||
|
||||
if neg {
|
||||
i -= 1u;
|
||||
*ptr::mut_offset(mp, i) = '-' as u8;
|
||||
}
|
||||
|
||||
vec::unsafe::form_slice(ptr::offset(p, i),
|
||||
len - i, f)
|
||||
}
|
||||
|
||||
assert 0u < i && i < len;
|
||||
|
||||
if neg {
|
||||
i -= 1u;
|
||||
*ptr::mut_offset(mp, i) = '-' as u8;
|
||||
}
|
||||
|
||||
vec::unsafe::form_slice(ptr::offset(p, i),
|
||||
len - i, f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,20 +45,24 @@ unsafe fn transmute<L, G>(-thing: L) -> G {
|
|||
mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_reinterpret_cast() unsafe {
|
||||
assert reinterpret_cast(1) == 1u;
|
||||
fn test_reinterpret_cast() {
|
||||
assert unsafe { reinterpret_cast(1) } == 1u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transmute() unsafe {
|
||||
let x = @1;
|
||||
let x: *int = transmute(x);
|
||||
assert *x == 1;
|
||||
let _x: @int = transmute(x);
|
||||
fn test_transmute() {
|
||||
unsafe {
|
||||
let x = @1;
|
||||
let x: *int = transmute(x);
|
||||
assert *x == 1;
|
||||
let _x: @int = transmute(x);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transmute2() unsafe {
|
||||
assert transmute("L") == [76u8, 0u8];
|
||||
fn test_transmute2() {
|
||||
unsafe {
|
||||
assert transmute("L") == [76u8, 0u8];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,14 +158,16 @@ fn reserve_at_least<T>(&v: [const T], n: uint) {
|
|||
Returns the number of elements the vector can hold without reallocating
|
||||
"]
|
||||
#[inline(always)]
|
||||
pure fn capacity<T>(&&v: [const T]) -> uint unsafe {
|
||||
let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
||||
(**repr).alloc / sys::size_of::<T>()
|
||||
pure fn capacity<T>(&&v: [const T]) -> uint {
|
||||
unsafe {
|
||||
let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
||||
(**repr).alloc / sys::size_of::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Returns the length of a vector"]
|
||||
#[inline(always)]
|
||||
pure fn len<T>(&&v: [const T]/&) -> uint unsafe {
|
||||
pure fn len<T>(&&v: [const T]/&) -> uint {
|
||||
unpack_const_slice(v) {|_p, len| len}
|
||||
}
|
||||
|
||||
|
@ -200,13 +202,13 @@ pure fn from_elem<T: copy>(n_elts: uint, t: T) -> [T] {
|
|||
}
|
||||
|
||||
#[doc = "Produces a mut vector from an immutable vector."]
|
||||
fn to_mut<T>(+v: [T]) -> [mut T] unsafe {
|
||||
::unsafe::transmute(v)
|
||||
fn to_mut<T>(+v: [T]) -> [mut T] {
|
||||
unsafe { ::unsafe::transmute(v) }
|
||||
}
|
||||
|
||||
#[doc = "Produces an immutable vector from a mut vector."]
|
||||
fn from_mut<T>(+v: [mut T]) -> [T] unsafe {
|
||||
::unsafe::transmute(v)
|
||||
fn from_mut<T>(+v: [mut T]) -> [T] {
|
||||
unsafe { ::unsafe::transmute(v) }
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
@ -406,13 +408,15 @@ fn unshift<T>(&v: [T], +x: T) {
|
|||
}
|
||||
|
||||
#[doc = "Remove the last element from a vector and return it"]
|
||||
fn pop<T>(&v: [const T]) -> T unsafe {
|
||||
fn pop<T>(&v: [const T]) -> T {
|
||||
let ln = len(v);
|
||||
assert ln > 0u;
|
||||
let valptr = ptr::mut_addr_of(v[ln - 1u]);
|
||||
let val <- *valptr;
|
||||
unsafe::set_len(v, ln - 1u);
|
||||
val
|
||||
unsafe {
|
||||
let val <- *valptr;
|
||||
unsafe::set_len(v, ln - 1u);
|
||||
val
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Append an element to a vector"]
|
||||
|
@ -963,13 +967,15 @@ Iterates over a vector, with option to break
|
|||
Return true to continue, false to break.
|
||||
"]
|
||||
#[inline(always)]
|
||||
pure fn each<T>(v: [const T]/&, f: fn(T) -> bool) unsafe {
|
||||
pure fn each<T>(v: [const T]/&, f: fn(T) -> bool) {
|
||||
vec::unpack_slice(v) {|p, n|
|
||||
let mut n = n;
|
||||
let mut p = p;
|
||||
while n > 0u {
|
||||
if !f(*p) { break; }
|
||||
p = ptr::offset(p, 1u);
|
||||
unsafe {
|
||||
if !f(*p) { break; }
|
||||
p = ptr::offset(p, 1u);
|
||||
}
|
||||
n -= 1u;
|
||||
}
|
||||
}
|
||||
|
@ -981,13 +987,15 @@ Iterates over a vector's elements and indices
|
|||
Return true to continue, false to break.
|
||||
"]
|
||||
#[inline(always)]
|
||||
pure fn eachi<T>(v: [const T]/&, f: fn(uint, T) -> bool) unsafe {
|
||||
pure fn eachi<T>(v: [const T]/&, f: fn(uint, T) -> bool) {
|
||||
vec::unpack_slice(v) {|p, n|
|
||||
let mut i = 0u;
|
||||
let mut p = p;
|
||||
while i < n {
|
||||
if !f(i, *p) { break; }
|
||||
p = ptr::offset(p, 1u);
|
||||
unsafe {
|
||||
if !f(i, *p) { break; }
|
||||
p = ptr::offset(p, 1u);
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
|
@ -1088,11 +1096,11 @@ Work with the buffer of a vector.
|
|||
Allows for unsafe manipulation of vector contents, which is useful for native
|
||||
interop.
|
||||
"]
|
||||
fn as_buf<E,T>(v: [E]/&, f: fn(*E) -> T) -> T unsafe {
|
||||
fn as_buf<E,T>(v: [E]/&, f: fn(*E) -> T) -> T {
|
||||
unpack_slice(v) { |buf, _len| f(buf) }
|
||||
}
|
||||
|
||||
fn as_mut_buf<E,T>(v: [mut E]/&, f: fn(*mut E) -> T) -> T unsafe {
|
||||
fn as_mut_buf<E,T>(v: [mut E]/&, f: fn(*mut E) -> T) -> T {
|
||||
unpack_mut_slice(v) { |buf, _len| f(buf) }
|
||||
}
|
||||
|
||||
|
@ -1101,10 +1109,12 @@ Work with the buffer and length of a slice.
|
|||
"]
|
||||
#[inline(always)]
|
||||
pure fn unpack_slice<T,U>(s: [const T]/&,
|
||||
f: fn(*T, uint) -> U) -> U unsafe {
|
||||
let v : *(*T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
let (buf,len) = *v;
|
||||
f(buf, len / sys::size_of::<T>())
|
||||
f: fn(*T, uint) -> U) -> U {
|
||||
unsafe {
|
||||
let v : *(*T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
let (buf,len) = *v;
|
||||
f(buf, len / sys::size_of::<T>())
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
|
@ -1112,10 +1122,13 @@ Work with the buffer and length of a slice.
|
|||
"]
|
||||
#[inline(always)]
|
||||
pure fn unpack_const_slice<T,U>(s: [const T]/&,
|
||||
f: fn(*const T, uint) -> U) -> U unsafe {
|
||||
let v : *(*const T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
let (buf,len) = *v;
|
||||
f(buf, len / sys::size_of::<T>())
|
||||
f: fn(*const T, uint) -> U) -> U {
|
||||
unsafe {
|
||||
let v : *(*const T,uint) =
|
||||
::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
let (buf,len) = *v;
|
||||
f(buf, len / sys::size_of::<T>())
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
|
@ -1123,10 +1136,13 @@ Work with the buffer and length of a slice.
|
|||
"]
|
||||
#[inline(always)]
|
||||
pure fn unpack_mut_slice<T,U>(s: [mut T]/&,
|
||||
f: fn(*mut T, uint) -> U) -> U unsafe {
|
||||
let v : *(*const T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
let (buf,len) = *v;
|
||||
f(buf, len / sys::size_of::<T>())
|
||||
f: fn(*mut T, uint) -> U) -> U {
|
||||
unsafe {
|
||||
let v : *(*const T,uint) =
|
||||
::unsafe::reinterpret_cast(ptr::addr_of(s));
|
||||
let (buf,len) = *v;
|
||||
f(buf, len / sys::size_of::<T>())
|
||||
}
|
||||
}
|
||||
|
||||
impl extensions<T: copy> for [T] {
|
||||
|
@ -1380,12 +1396,14 @@ mod u8 {
|
|||
export hash;
|
||||
|
||||
#[doc = "Bytewise string comparison"]
|
||||
pure fn cmp(&&a: [u8], &&b: [u8]) -> int unsafe {
|
||||
pure fn cmp(&&a: [u8], &&b: [u8]) -> int {
|
||||
let a_len = len(a);
|
||||
let b_len = len(b);
|
||||
let n = uint::min(a_len, b_len) as libc::size_t;
|
||||
let r = libc::memcmp(unsafe::to_ptr(a) as *libc::c_void,
|
||||
unsafe::to_ptr(b) as *libc::c_void, n) as int;
|
||||
let r = unsafe {
|
||||
libc::memcmp(unsafe::to_ptr(a) as *libc::c_void,
|
||||
unsafe::to_ptr(b) as *libc::c_void, n) as int
|
||||
};
|
||||
|
||||
if r != 0 { r } else {
|
||||
if a_len == b_len {
|
||||
|
@ -1405,10 +1423,10 @@ mod u8 {
|
|||
pure fn le(&&a: [u8], &&b: [u8]) -> bool { cmp(a, b) <= 0 }
|
||||
|
||||
#[doc = "Bytewise equality"]
|
||||
pure fn eq(&&a: [u8], &&b: [u8]) -> bool unsafe { cmp(a, b) == 0 }
|
||||
pure fn eq(&&a: [u8], &&b: [u8]) -> bool { unsafe { cmp(a, b) == 0 } }
|
||||
|
||||
#[doc = "Bytewise inequality"]
|
||||
pure fn ne(&&a: [u8], &&b: [u8]) -> bool unsafe { cmp(a, b) != 0 }
|
||||
pure fn ne(&&a: [u8], &&b: [u8]) -> bool { unsafe { cmp(a, b) != 0 } }
|
||||
|
||||
#[doc ="Bytewise greater than or equal"]
|
||||
pure fn ge(&&a: [u8], &&b: [u8]) -> bool { cmp(a, b) >= 0 }
|
||||
|
@ -1482,26 +1500,28 @@ mod tests {
|
|||
fn add(&&x: uint, &&y: uint) -> uint { ret x + y; }
|
||||
|
||||
#[test]
|
||||
fn test_unsafe_ptrs() unsafe {
|
||||
// Test on-stack copy-from-buf.
|
||||
let a = [1, 2, 3];
|
||||
let mut ptr = unsafe::to_ptr(a);
|
||||
let b = unsafe::from_buf(ptr, 3u);
|
||||
assert (len(b) == 3u);
|
||||
assert (b[0] == 1);
|
||||
assert (b[1] == 2);
|
||||
assert (b[2] == 3);
|
||||
fn test_unsafe_ptrs() {
|
||||
unsafe {
|
||||
// Test on-stack copy-from-buf.
|
||||
let a = [1, 2, 3];
|
||||
let mut ptr = unsafe::to_ptr(a);
|
||||
let b = unsafe::from_buf(ptr, 3u);
|
||||
assert (len(b) == 3u);
|
||||
assert (b[0] == 1);
|
||||
assert (b[1] == 2);
|
||||
assert (b[2] == 3);
|
||||
|
||||
// Test on-heap copy-from-buf.
|
||||
let c = [1, 2, 3, 4, 5];
|
||||
ptr = unsafe::to_ptr(c);
|
||||
let d = unsafe::from_buf(ptr, 5u);
|
||||
assert (len(d) == 5u);
|
||||
assert (d[0] == 1);
|
||||
assert (d[1] == 2);
|
||||
assert (d[2] == 3);
|
||||
assert (d[3] == 4);
|
||||
assert (d[4] == 5);
|
||||
// Test on-heap copy-from-buf.
|
||||
let c = [1, 2, 3, 4, 5];
|
||||
ptr = unsafe::to_ptr(c);
|
||||
let d = unsafe::from_buf(ptr, 5u);
|
||||
assert (len(d) == 5u);
|
||||
assert (d[0] == 1);
|
||||
assert (d[1] == 2);
|
||||
assert (d[2] == 3);
|
||||
assert (d[3] == 4);
|
||||
assert (d[4] == 5);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2189,21 +2209,25 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn to_mut_no_copy() unsafe {
|
||||
let x = [1, 2, 3];
|
||||
let addr = unsafe::to_ptr(x);
|
||||
let x_mut = to_mut(x);
|
||||
let addr_mut = unsafe::to_ptr(x_mut);
|
||||
assert addr == addr_mut;
|
||||
fn to_mut_no_copy() {
|
||||
unsafe {
|
||||
let x = [1, 2, 3];
|
||||
let addr = unsafe::to_ptr(x);
|
||||
let x_mut = to_mut(x);
|
||||
let addr_mut = unsafe::to_ptr(x_mut);
|
||||
assert addr == addr_mut;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_mut_no_copy() unsafe {
|
||||
let x = [mut 1, 2, 3];
|
||||
let addr = unsafe::to_ptr(x);
|
||||
let x_imm = from_mut(x);
|
||||
let addr_imm = unsafe::to_ptr(x_imm);
|
||||
assert addr == addr_imm;
|
||||
fn from_mut_no_copy() {
|
||||
unsafe {
|
||||
let x = [mut 1, 2, 3];
|
||||
let addr = unsafe::to_ptr(x);
|
||||
let x_imm = from_mut(x);
|
||||
let addr_imm = unsafe::to_ptr(x_imm);
|
||||
assert addr == addr_imm;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue